From fe3f6fb6c819bb33cff00ed57136956488d2a867 Mon Sep 17 00:00:00 2001 From: Ingmar Goudt Date: Sun, 30 Sep 2018 12:48:03 +0200 Subject: [PATCH 001/167] make plane and emblem implement Controllable to give access to the isControlledBy method --- Mage.Sets/src/mage/cards/c/CelestialDawn.java | 2 +- Mage.Sets/src/mage/cards/c/CoverOfWinter.java | 2 +- Mage.Sets/src/mage/cards/e/EmissaryOfGrudges.java | 4 ++-- Mage.Sets/src/mage/cards/s/SavageSummoning.java | 2 +- Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java | 4 ++-- Mage/src/main/java/mage/game/Controllable.java | 3 +++ Mage/src/main/java/mage/game/GameImpl.java | 2 +- Mage/src/main/java/mage/game/command/CommandObject.java | 5 ++--- 8 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CelestialDawn.java b/Mage.Sets/src/mage/cards/c/CelestialDawn.java index 787eaf39cc..babf9c8d24 100644 --- a/Mage.Sets/src/mage/cards/c/CelestialDawn.java +++ b/Mage.Sets/src/mage/cards/c/CelestialDawn.java @@ -135,7 +135,7 @@ class CelestialDawnToWhiteEffect extends ContinuousEffectImpl { // Command for (CommandObject commandObject : game.getState().getCommand()) { if (commandObject instanceof Commander) { - if (commandObject.getControllerId().equals(controller.getId())) { + if (commandObject.isControlledBy(controller.getId())) { setColor(commandObject.getColor(game), game); } } diff --git a/Mage.Sets/src/mage/cards/c/CoverOfWinter.java b/Mage.Sets/src/mage/cards/c/CoverOfWinter.java index 5497f041bb..7d9fdfa426 100644 --- a/Mage.Sets/src/mage/cards/c/CoverOfWinter.java +++ b/Mage.Sets/src/mage/cards/c/CoverOfWinter.java @@ -88,7 +88,7 @@ class CoverOfWinterEffect extends PreventionEffectImpl { if (event.getType() == GameEvent.EventType.DAMAGE_CREATURE) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { return super.applies(event, source, game); } } diff --git a/Mage.Sets/src/mage/cards/e/EmissaryOfGrudges.java b/Mage.Sets/src/mage/cards/e/EmissaryOfGrudges.java index 9bd4c2fa1f..0f1f1141c2 100644 --- a/Mage.Sets/src/mage/cards/e/EmissaryOfGrudges.java +++ b/Mage.Sets/src/mage/cards/e/EmissaryOfGrudges.java @@ -94,11 +94,11 @@ class EmissaryOfGrudgesEffect extends OneShotEffect { Mode mode = stackObject.getStackAbility().getModes().get(modeId); for (Target target : mode.getTargets()) { for (UUID targetId : target.getTargets()) { - if (source.getControllerId().equals(targetId)) { + if (source.isControlledBy(targetId)) { targetsYouOrAPermanentYouControl = true; } Permanent permanent = game.getPermanent(targetId); - if (permanent != null && source.getControllerId().equals(permanent.getControllerId())) { + if (permanent != null && source.isControlledBy(permanent.getControllerId())) { targetsYouOrAPermanentYouControl = true; } } diff --git a/Mage.Sets/src/mage/cards/s/SavageSummoning.java b/Mage.Sets/src/mage/cards/s/SavageSummoning.java index 2d19dea4fb..df81be34d6 100644 --- a/Mage.Sets/src/mage/cards/s/SavageSummoning.java +++ b/Mage.Sets/src/mage/cards/s/SavageSummoning.java @@ -100,7 +100,7 @@ class SavageSummoningAsThoughEffect extends AsThoughEffectImpl { MageObject mageObject = game.getBaseObject(objectId); if (mageObject instanceof Commander) { Commander commander = (Commander) mageObject; - if (commander.isCreature() && commander.getControllerId().equals(source.getControllerId())) { + if (commander.isCreature() && commander.isControlledBy(source.getControllerId())) { return true; } } else if (mageObject instanceof Card) { diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index 6b48461d8f..21fac77d7a 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -219,9 +219,9 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } else { MageObject mageObject = game.getObject(this.sourceId); if (mageObject instanceof Emblem) { - return ((Emblem) mageObject).getControllerId().equals(playerId); + return ((Emblem) mageObject).isControlledBy(playerId); } else if (mageObject instanceof Plane) { - return ((Plane) mageObject).getControllerId().equals(playerId); + return ((Plane) mageObject).isControlledBy(playerId); } else if (game.getState().getZone(this.sourceId) != Zone.BATTLEFIELD) { return ((Card) mageObject).isOwnedBy(playerId); } diff --git a/Mage/src/main/java/mage/game/Controllable.java b/Mage/src/main/java/mage/game/Controllable.java index 025b8f3720..ac7507e508 100644 --- a/Mage/src/main/java/mage/game/Controllable.java +++ b/Mage/src/main/java/mage/game/Controllable.java @@ -12,6 +12,9 @@ public interface Controllable { UUID getId(); default boolean isControlledBy(UUID controllerID){ + if(getControllerId() == null){ + return false; + } return getControllerId().equals(controllerID); } } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index e745c75e12..8f5234fb00 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -2594,7 +2594,7 @@ public abstract class GameImpl implements Game, Serializable { boolean addPlaneAgain = false; for (Iterator it = this.getState().getCommand().iterator(); it.hasNext();) { CommandObject obj = it.next(); - if (obj.getControllerId().equals(playerId)) { + if (obj.isControlledBy(playerId)) { if (obj instanceof Emblem) { ((Emblem) obj).discardEffects();// This may not be the best fix but it works } diff --git a/Mage/src/main/java/mage/game/command/CommandObject.java b/Mage/src/main/java/mage/game/command/CommandObject.java index b537d823ea..2a376c6b3f 100644 --- a/Mage/src/main/java/mage/game/command/CommandObject.java +++ b/Mage/src/main/java/mage/game/command/CommandObject.java @@ -3,17 +3,16 @@ package mage.game.command; import java.util.UUID; import mage.MageObject; +import mage.game.Controllable; /** * * @author Viserion, nantuko */ -public interface CommandObject extends MageObject { +public interface CommandObject extends MageObject, Controllable { UUID getSourceId(); - UUID getControllerId(); - void assignNewId(); MageObject getSourceObject(); From 650986a83ca16e2b16e8f0338af4ce3e3db2feab Mon Sep 17 00:00:00 2001 From: L_J Date: Sun, 30 Sep 2018 20:49:23 +0200 Subject: [PATCH 002/167] Implemented Unstable cards & fixes --- Mage.Sets/src/mage/cards/b/BeastInShow.java | 36 ++++ .../src/mage/cards/d/DelightedKillbot.java | 33 ++++ .../src/mage/cards/d/DespondentKillbot.java | 33 ++++ .../src/mage/cards/e/EnragedKillbot.java | 33 ++++ Mage.Sets/src/mage/cards/h/HammerJammer.java | 154 ++++++++++++++++++ Mage.Sets/src/mage/cards/n/Novellamental.java | 39 +++++ .../mage/cards/s/StaffOfTheLetterMagus.java | 145 +++++++++++++++++ Mage.Sets/src/mage/sets/Unstable.java | 30 +++- 8 files changed, 497 insertions(+), 6 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/b/BeastInShow.java create mode 100644 Mage.Sets/src/mage/cards/d/DelightedKillbot.java create mode 100644 Mage.Sets/src/mage/cards/d/DespondentKillbot.java create mode 100644 Mage.Sets/src/mage/cards/e/EnragedKillbot.java create mode 100644 Mage.Sets/src/mage/cards/h/HammerJammer.java create mode 100644 Mage.Sets/src/mage/cards/n/Novellamental.java create mode 100644 Mage.Sets/src/mage/cards/s/StaffOfTheLetterMagus.java diff --git a/Mage.Sets/src/mage/cards/b/BeastInShow.java b/Mage.Sets/src/mage/cards/b/BeastInShow.java new file mode 100644 index 0000000000..d865d0baed --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BeastInShow.java @@ -0,0 +1,36 @@ + +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author L_J + */ +public final class BeastInShow extends CardImpl { + + public BeastInShow(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); + this.subtype.add(SubType.BEAST); + this.power = new MageInt(6); + this.toughness = new MageInt(4); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + } + + public BeastInShow(final BeastInShow card) { + super(card); + } + + @Override + public BeastInShow copy() { + return new BeastInShow(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DelightedKillbot.java b/Mage.Sets/src/mage/cards/d/DelightedKillbot.java new file mode 100644 index 0000000000..a5138ced2d --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DelightedKillbot.java @@ -0,0 +1,33 @@ + +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author spjspj + */ +public final class DelightedKillbot extends CardImpl { + + public DelightedKillbot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); + + this.subtype.add(SubType.KILLBOT); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + } + + public DelightedKillbot(final DelightedKillbot card) { + super(card); + } + + @Override + public DelightedKillbot copy() { + return new DelightedKillbot(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DespondentKillbot.java b/Mage.Sets/src/mage/cards/d/DespondentKillbot.java new file mode 100644 index 0000000000..3f4dde3130 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DespondentKillbot.java @@ -0,0 +1,33 @@ + +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author spjspj + */ +public final class DespondentKillbot extends CardImpl { + + public DespondentKillbot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); + + this.subtype.add(SubType.KILLBOT); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + } + + public DespondentKillbot(final DespondentKillbot card) { + super(card); + } + + @Override + public DespondentKillbot copy() { + return new DespondentKillbot(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EnragedKillbot.java b/Mage.Sets/src/mage/cards/e/EnragedKillbot.java new file mode 100644 index 0000000000..6137f31eea --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EnragedKillbot.java @@ -0,0 +1,33 @@ + +package mage.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author spjspj + */ +public final class EnragedKillbot extends CardImpl { + + public EnragedKillbot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); + + this.subtype.add(SubType.KILLBOT); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + } + + public EnragedKillbot(final EnragedKillbot card) { + super(card); + } + + @Override + public EnragedKillbot copy() { + return new EnragedKillbot(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HammerJammer.java b/Mage.Sets/src/mage/cards/h/HammerJammer.java new file mode 100644 index 0000000000..52e51e3d4b --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HammerJammer.java @@ -0,0 +1,154 @@ + +package mage.cards.h; + +import java.util.ArrayList; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author spjspj & L_J + */ +public final class HammerJammer extends CardImpl { + + public HammerJammer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // As Hammer Jammer enters the battlefield, roll a six-sided die. Hammer Jammer enters the battlefield with a number of +1/+1 counters on it equal to the result. + this.addAbility(new EntersBattlefieldAbility(new HammerJammerEntersEffect(CounterType.P1P1.createInstance()))); + + // Whenever you roll a die, remove all +1/+1 counters from Hammer Jammer, then put a number of +1/+1 counters on it equal to the result. + this.addAbility(new HammerJammerTriggeredAbility()); + + } + + public HammerJammer(final HammerJammer card) { + super(card); + } + + @Override + public HammerJammer copy() { + return new HammerJammer(this); + } +} + +class HammerJammerEntersEffect extends EntersBattlefieldWithXCountersEffect { + + public HammerJammerEntersEffect(Counter counter) { + super(counter); + } + + public HammerJammerEntersEffect(EntersBattlefieldWithXCountersEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); + if (controller != null && permanent != null) { + int amount = controller.rollDice(game, 6); + ArrayList appliedEffects = (ArrayList) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event + permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game, appliedEffects); + return super.apply(game, source); + } + return false; + } + + @Override + public EntersBattlefieldWithXCountersEffect copy() { + return new HammerJammerEntersEffect(this); + } +} + +class HammerJammerTriggeredAbility extends TriggeredAbilityImpl { + + public HammerJammerTriggeredAbility() { + super(Zone.BATTLEFIELD, new HammerJammerEffect(), false); + } + + public HammerJammerTriggeredAbility(final HammerJammerTriggeredAbility ability) { + super(ability); + } + + @Override + public HammerJammerTriggeredAbility copy() { + return new HammerJammerTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DICE_ROLLED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (this.getControllerId().equals(event.getPlayerId()) && event.getFlag()) { + for (Effect effect : this.getEffects()) { + effect.setValue("rolled", event.getAmount()); + } + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you roll a die, " + super.getRule(); + } +} + +class HammerJammerEffect extends OneShotEffect { + + public HammerJammerEffect() { + super(Outcome.Benefit); + this.staticText = "remove all +1/+1 counters from {this}, then put a number of +1/+1 counters on it equal to the result"; + } + + public HammerJammerEffect(final HammerJammerEffect effect) { + super(effect); + } + + @Override + public HammerJammerEffect copy() { + return new HammerJammerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (controller != null && permanent != null) { + if (getValue("rolled") != null) { + int amount = (Integer) getValue("rolled"); + permanent.removeCounters(CounterType.P1P1.createInstance(permanent.getCounters(game).getCount(CounterType.P1P1)), game); + permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game); + return true; + } + } + return false; + + } +} diff --git a/Mage.Sets/src/mage/cards/n/Novellamental.java b/Mage.Sets/src/mage/cards/n/Novellamental.java new file mode 100644 index 0000000000..e81323db4b --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/Novellamental.java @@ -0,0 +1,39 @@ + +package mage.cards.n; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.CanBlockOnlyFlyingAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author L_J + */ +public final class Novellamental extends CardImpl { + + public Novellamental(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Novellamental can block only creatures with flying. + this.addAbility(new CanBlockOnlyFlyingAbility()); + } + + public Novellamental(final Novellamental card) { + super(card); + } + + @Override + public Novellamental copy() { + return new Novellamental(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/StaffOfTheLetterMagus.java b/Mage.Sets/src/mage/cards/s/StaffOfTheLetterMagus.java new file mode 100644 index 0000000000..b31f034cc6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StaffOfTheLetterMagus.java @@ -0,0 +1,145 @@ + +package mage.cards.s; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SpellCastAllTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.filter.FilterSpell; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author L_J + */ +public final class StaffOfTheLetterMagus extends CardImpl { + + public StaffOfTheLetterMagus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + + // As Staff of the Letter Magus enters the battlefield, choose a consonant other than N, R, S, or T. + this.addAbility(new AsEntersBattlefieldAbility(new StaffOfTheLetterMagusChooseLetterEffect())); + + // Whenever a player casts a spell, you gain 1 life for each time the chosen letter appears in that spell’s name. + this.addAbility(new SpellCastAllTriggeredAbility(new StaffOfTheLetterMagusEffect(), new FilterSpell("a spell"), false, SetTargetPointer.SPELL)); + } + + public StaffOfTheLetterMagus(final StaffOfTheLetterMagus card) { + super(card); + } + + @Override + public StaffOfTheLetterMagus copy() { + return new StaffOfTheLetterMagus(this); + } +} + +class StaffOfTheLetterMagusChooseLetterEffect extends OneShotEffect { + + public StaffOfTheLetterMagusChooseLetterEffect() { + super(Outcome.Benefit); + staticText = "choose a consonant other than N, R, S, or T"; + } + + public StaffOfTheLetterMagusChooseLetterEffect(final StaffOfTheLetterMagusChooseLetterEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + + ChoiceImpl choice = new ChoiceImpl(true); + choice.setMessage("Choose letter"); + Set choices = new HashSet<>(); + // Can I choose Y? + // Yes. We play by popular game show rules here. Y is a consonant. + // https://magic.wizards.com/en/articles/archive/news/unstable-faqawaslfaqpaftidawabiajtbt-2017-12-06 + Character[] forbiddenChars = {'A','E','I','N','O','R','S','T','U'}; + for (Character letter = 'A'; letter <= 'Z'; letter++) { + if (Arrays.binarySearch(forbiddenChars, letter) < 0) { + choices.add(letter.toString()); + } + } + choice.setChoices(choices); + + if (controller != null && mageObject != null && controller.choose(outcome, choice, game)) { + if (!game.isSimulation()) { + game.informPlayers(mageObject.getLogName() + ": " + controller.getLogName() + " has chosen " + choice.getChoice()); + } + game.getState().setValue(mageObject.getId() + "_letter", choice.getChoice()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosen letter", CardUtil.addToolTipMarkTags("Chosen letter: " + choice.getChoice()), game); + } + return true; + } + return false; + } + + @Override + public StaffOfTheLetterMagusChooseLetterEffect copy() { + return new StaffOfTheLetterMagusChooseLetterEffect(this); + } +} + +class StaffOfTheLetterMagusEffect extends OneShotEffect { + + public StaffOfTheLetterMagusEffect() { + super(Outcome.GainLife); + staticText = "you gain 1 life for each time the chosen letter appears in that spell’s name"; + } + + public StaffOfTheLetterMagusEffect(final StaffOfTheLetterMagusEffect effect) { + super(effect); + } + + @Override + public StaffOfTheLetterMagusEffect copy() { + return new StaffOfTheLetterMagusEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source)); + if (controller != null && spell != null) { + MageObject mageObject = game.getObject(source.getSourceId()); + if (mageObject instanceof Permanent) { + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (permanent != null && game.getState().getValue(mageObject.getId() + "_letter") != null) { + int lifegainValue = 0; + String spellName = spell.getName(); + for (int i = 0; i < spellName.length(); i++) { + Character letter = spellName.charAt(i); + String chosenLetter = (String) game.getState().getValue(mageObject.getId() + "_letter"); + if (Character.isLetter(letter) && Character.toUpperCase(letter) == chosenLetter.charAt(0)) { + lifegainValue++; + } + } + controller.gainLife(lifegainValue, game, source); + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Unstable.java b/Mage.Sets/src/mage/sets/Unstable.java index a30cc6a628..8cc1cb58ba 100644 --- a/Mage.Sets/src/mage/sets/Unstable.java +++ b/Mage.Sets/src/mage/sets/Unstable.java @@ -21,22 +21,32 @@ public final class Unstable extends ExpansionSet { private Unstable() { super("Unstable", "UST", ExpansionSet.buildDate(2017, 12, 8), SetType.JOKESET); - - cards.add(new SetCardInfo("Amateur Auteur", 3, Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); + cards.add(new SetCardInfo("Amateur Auteur", "3a", Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); + cards.add(new SetCardInfo("Amateur Auteur", "3b", Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); + cards.add(new SetCardInfo("Amateur Auteur", "3c", Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); + cards.add(new SetCardInfo("Amateur Auteur", "3d", Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); cards.add(new SetCardInfo("As Luck Would Have It", 102, Rarity.RARE, mage.cards.a.AsLuckWouldHaveIt.class)); cards.add(new SetCardInfo("Baron Von Count", 127, Rarity.MYTHIC, mage.cards.b.BaronVonCount.class)); + cards.add(new SetCardInfo("Beast in Show", "103a", Rarity.COMMON, mage.cards.b.BeastInShow.class)); + cards.add(new SetCardInfo("Beast in Show", "103b", Rarity.COMMON, mage.cards.b.BeastInShow.class)); + cards.add(new SetCardInfo("Beast in Show", "103c", Rarity.COMMON, mage.cards.b.BeastInShow.class)); + cards.add(new SetCardInfo("Beast in Show", "103d", Rarity.COMMON, mage.cards.b.BeastInShow.class)); cards.add(new SetCardInfo("Box of Free-Range Goblins", 77, Rarity.COMMON, mage.cards.b.BoxOfFreerangeGoblins.class)); cards.add(new SetCardInfo("Buzzing Whack-a-Doodle", 141, Rarity.UNCOMMON, mage.cards.b.BuzzingWhackADoodle.class)); cards.add(new SetCardInfo("Chittering Doom", 104, Rarity.UNCOMMON, mage.cards.c.ChitteringDoom.class)); cards.add(new SetCardInfo("Crow Storm", 31, Rarity.UNCOMMON, mage.cards.c.CrowStorm.class)); - cards.add(new SetCardInfo("Curious Killbot", 145, Rarity.COMMON, mage.cards.c.CuriousKillbot.class)); + cards.add(new SetCardInfo("Curious Killbot", "145a", Rarity.COMMON, mage.cards.c.CuriousKillbot.class)); + cards.add(new SetCardInfo("Delighted Killbot", "145b", Rarity.COMMON, mage.cards.d.DelightedKillbot.class)); + cards.add(new SetCardInfo("Despondent Killbot", "145c", Rarity.COMMON, mage.cards.d.DespondentKillbot.class)); cards.add(new SetCardInfo("Dr. Julius Jumblemorph", 130, Rarity.MYTHIC, mage.cards.d.DrJuliusJumblemorph.class)); + cards.add(new SetCardInfo("Enraged Killbot", "145d", Rarity.COMMON, mage.cards.e.EnragedKillbot.class)); cards.add(new SetCardInfo("Earl of Squirrel", 108, Rarity.RARE, mage.cards.e.EarlOfSquirrel.class)); cards.add(new SetCardInfo("Forest", 216, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false))); cards.add(new SetCardInfo("GO TO JAIL", 8, Rarity.COMMON, mage.cards.g.GOTOJAIL.class)); cards.add(new SetCardInfo("Garbage Elemental", "82c", Rarity.UNCOMMON, mage.cards.g.GarbageElementalC.class)); cards.add(new SetCardInfo("Ground Pounder", 110, Rarity.COMMON, mage.cards.g.GroundPounder.class)); cards.add(new SetCardInfo("Hammer Helper", 85, Rarity.COMMON, mage.cards.h.HammerHelper.class)); + cards.add(new SetCardInfo("Hammer Jammer", 86, Rarity.UNCOMMON, mage.cards.h.HammerJammer.class)); cards.add(new SetCardInfo("Hydradoodle", 112, Rarity.RARE, mage.cards.h.Hydradoodle.class)); cards.add(new SetCardInfo("Inhumaniac", 59, Rarity.UNCOMMON, mage.cards.i.Inhumaniac.class)); cards.add(new SetCardInfo("Island", 213, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false))); @@ -44,18 +54,26 @@ public final class Unstable extends ExpansionSet { cards.add(new SetCardInfo("Lobe Lobber", 153, Rarity.UNCOMMON, mage.cards.l.LobeLobber.class)); cards.add(new SetCardInfo("Mad Science Fair Project", 154, Rarity.COMMON, mage.cards.m.MadScienceFairProject.class)); cards.add(new SetCardInfo("Mountain", 215, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false))); + cards.add(new SetCardInfo("Novellamental", "41a", Rarity.COMMON, mage.cards.n.Novellamental.class)); + cards.add(new SetCardInfo("Novellamental", "41b", Rarity.COMMON, mage.cards.n.Novellamental.class)); + cards.add(new SetCardInfo("Novellamental", "41c", Rarity.COMMON, mage.cards.n.Novellamental.class)); + cards.add(new SetCardInfo("Novellamental", "41d", Rarity.COMMON, mage.cards.n.Novellamental.class)); cards.add(new SetCardInfo("Oddly Uneven", 15, Rarity.RARE, mage.cards.o.OddlyUneven.class)); cards.add(new SetCardInfo("Painiac", 91, Rarity.COMMON, mage.cards.p.Painiac.class)); cards.add(new SetCardInfo("Plains", 212, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false))); cards.add(new SetCardInfo("Snickering Squirrel", 68, Rarity.COMMON, mage.cards.s.SnickeringSquirrel.class)); cards.add(new SetCardInfo("Squirrel-Powered Scheme", 70, Rarity.UNCOMMON, mage.cards.s.SquirrelPoweredScheme.class)); + cards.add(new SetCardInfo("Staff of the Letter Magus", 159, Rarity.UNCOMMON, mage.cards.s.StaffOfTheLetterMagus.class)); cards.add(new SetCardInfo("Steamflogger Boss", 93, Rarity.RARE, mage.cards.s.SteamfloggerBoss.class)); cards.add(new SetCardInfo("Steel Squirrel", 162, Rarity.UNCOMMON, mage.cards.s.SteelSquirrel.class)); cards.add(new SetCardInfo("Summon the Pack", 74, Rarity.MYTHIC, mage.cards.s.SummonThePack.class)); cards.add(new SetCardInfo("Swamp", 214, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false))); - cards.add(new SetCardInfo("Sword of Dungeons & Dragons", 1, Rarity.MYTHIC, mage.cards.s.SwordOfDungeonsAndDragons.class)); - cards.add(new SetCardInfo("Target Minotaur", 98, Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); - cards.add(new SetCardInfo("The Big Idea", "76", Rarity.RARE, mage.cards.t.TheBigIdea.class)); + cards.add(new SetCardInfo("Sword of Dungeons & Dragons", 163, Rarity.MYTHIC, mage.cards.s.SwordOfDungeonsAndDragons.class)); + cards.add(new SetCardInfo("Target Minotaur", "98a", Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); + cards.add(new SetCardInfo("Target Minotaur", "98b", Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); + cards.add(new SetCardInfo("Target Minotaur", "98c", Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); + cards.add(new SetCardInfo("Target Minotaur", "98d", Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); + cards.add(new SetCardInfo("The Big Idea", 76, Rarity.RARE, mage.cards.t.TheBigIdea.class)); cards.add(new SetCardInfo("Time Out", 48, Rarity.COMMON, mage.cards.t.TimeOut.class)); cards.add(new SetCardInfo("Very Cryptic Command", "49d", Rarity.RARE, mage.cards.v.VeryCrypticCommandD.class)); cards.add(new SetCardInfo("Willing Test Subject", 126, Rarity.COMMON, mage.cards.w.WillingTestSubject.class)); From 31bf2f578422439597fbf4c5c35be4bb5158f868 Mon Sep 17 00:00:00 2001 From: L_J Date: Sun, 30 Sep 2018 20:30:38 +0000 Subject: [PATCH 003/167] NON_FULL_USE_VARIOUS fix --- Mage.Sets/src/mage/sets/Unstable.java | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Unstable.java b/Mage.Sets/src/mage/sets/Unstable.java index 8cc1cb58ba..83d3a8dd3a 100644 --- a/Mage.Sets/src/mage/sets/Unstable.java +++ b/Mage.Sets/src/mage/sets/Unstable.java @@ -21,16 +21,17 @@ public final class Unstable extends ExpansionSet { private Unstable() { super("Unstable", "UST", ExpansionSet.buildDate(2017, 12, 8), SetType.JOKESET); - cards.add(new SetCardInfo("Amateur Auteur", "3a", Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); - cards.add(new SetCardInfo("Amateur Auteur", "3b", Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); - cards.add(new SetCardInfo("Amateur Auteur", "3c", Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); - cards.add(new SetCardInfo("Amateur Auteur", "3d", Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); + + cards.add(new SetCardInfo("Amateur Auteur", "3a", Rarity.COMMON, mage.cards.a.AmateurAuteur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Amateur Auteur", "3b", Rarity.COMMON, mage.cards.a.AmateurAuteur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Amateur Auteur", "3c", Rarity.COMMON, mage.cards.a.AmateurAuteur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Amateur Auteur", "3d", Rarity.COMMON, mage.cards.a.AmateurAuteur.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("As Luck Would Have It", 102, Rarity.RARE, mage.cards.a.AsLuckWouldHaveIt.class)); cards.add(new SetCardInfo("Baron Von Count", 127, Rarity.MYTHIC, mage.cards.b.BaronVonCount.class)); - cards.add(new SetCardInfo("Beast in Show", "103a", Rarity.COMMON, mage.cards.b.BeastInShow.class)); - cards.add(new SetCardInfo("Beast in Show", "103b", Rarity.COMMON, mage.cards.b.BeastInShow.class)); - cards.add(new SetCardInfo("Beast in Show", "103c", Rarity.COMMON, mage.cards.b.BeastInShow.class)); - cards.add(new SetCardInfo("Beast in Show", "103d", Rarity.COMMON, mage.cards.b.BeastInShow.class)); + cards.add(new SetCardInfo("Beast in Show", "103a", Rarity.COMMON, mage.cards.b.BeastInShow.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Beast in Show", "103b", Rarity.COMMON, mage.cards.b.BeastInShow.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Beast in Show", "103c", Rarity.COMMON, mage.cards.b.BeastInShow.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Beast in Show", "103d", Rarity.COMMON, mage.cards.b.BeastInShow.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Box of Free-Range Goblins", 77, Rarity.COMMON, mage.cards.b.BoxOfFreerangeGoblins.class)); cards.add(new SetCardInfo("Buzzing Whack-a-Doodle", 141, Rarity.UNCOMMON, mage.cards.b.BuzzingWhackADoodle.class)); cards.add(new SetCardInfo("Chittering Doom", 104, Rarity.UNCOMMON, mage.cards.c.ChitteringDoom.class)); @@ -54,10 +55,10 @@ public final class Unstable extends ExpansionSet { cards.add(new SetCardInfo("Lobe Lobber", 153, Rarity.UNCOMMON, mage.cards.l.LobeLobber.class)); cards.add(new SetCardInfo("Mad Science Fair Project", 154, Rarity.COMMON, mage.cards.m.MadScienceFairProject.class)); cards.add(new SetCardInfo("Mountain", 215, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false))); - cards.add(new SetCardInfo("Novellamental", "41a", Rarity.COMMON, mage.cards.n.Novellamental.class)); - cards.add(new SetCardInfo("Novellamental", "41b", Rarity.COMMON, mage.cards.n.Novellamental.class)); - cards.add(new SetCardInfo("Novellamental", "41c", Rarity.COMMON, mage.cards.n.Novellamental.class)); - cards.add(new SetCardInfo("Novellamental", "41d", Rarity.COMMON, mage.cards.n.Novellamental.class)); + cards.add(new SetCardInfo("Novellamental", "41a", Rarity.COMMON, mage.cards.n.Novellamental.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Novellamental", "41b", Rarity.COMMON, mage.cards.n.Novellamental.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Novellamental", "41c", Rarity.COMMON, mage.cards.n.Novellamental.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Novellamental", "41d", Rarity.COMMON, mage.cards.n.Novellamental.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Oddly Uneven", 15, Rarity.RARE, mage.cards.o.OddlyUneven.class)); cards.add(new SetCardInfo("Painiac", 91, Rarity.COMMON, mage.cards.p.Painiac.class)); cards.add(new SetCardInfo("Plains", 212, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false))); @@ -69,10 +70,10 @@ public final class Unstable extends ExpansionSet { cards.add(new SetCardInfo("Summon the Pack", 74, Rarity.MYTHIC, mage.cards.s.SummonThePack.class)); cards.add(new SetCardInfo("Swamp", 214, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false))); cards.add(new SetCardInfo("Sword of Dungeons & Dragons", 163, Rarity.MYTHIC, mage.cards.s.SwordOfDungeonsAndDragons.class)); - cards.add(new SetCardInfo("Target Minotaur", "98a", Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); - cards.add(new SetCardInfo("Target Minotaur", "98b", Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); - cards.add(new SetCardInfo("Target Minotaur", "98c", Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); - cards.add(new SetCardInfo("Target Minotaur", "98d", Rarity.COMMON, mage.cards.t.TargetMinotaur.class)); + cards.add(new SetCardInfo("Target Minotaur", "98a", Rarity.COMMON, mage.cards.t.TargetMinotaur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Target Minotaur", "98b", Rarity.COMMON, mage.cards.t.TargetMinotaur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Target Minotaur", "98c", Rarity.COMMON, mage.cards.t.TargetMinotaur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Target Minotaur", "98d", Rarity.COMMON, mage.cards.t.TargetMinotaur.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Big Idea", 76, Rarity.RARE, mage.cards.t.TheBigIdea.class)); cards.add(new SetCardInfo("Time Out", 48, Rarity.COMMON, mage.cards.t.TimeOut.class)); cards.add(new SetCardInfo("Very Cryptic Command", "49d", Rarity.RARE, mage.cards.v.VeryCrypticCommandD.class)); From 29f6f1c4b8fce4b658a3d8f7b2775d2ede38f7e6 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 30 Sep 2018 23:15:58 +0200 Subject: [PATCH 004/167] XMage 1.4.31V4 --- Mage.Common/src/main/java/mage/utils/MageVersion.java | 2 +- Mage/src/main/java/mage/cards/repository/CardRepository.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index ddd0fefe4a..4a0feb9728 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -14,7 +14,7 @@ public class MageVersion implements Serializable, Comparable { public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 31; - public final static String MAGE_VERSION_MINOR_PATCH = "V3"; + public final static String MAGE_VERSION_MINOR_PATCH = "V4"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 6fbb195bfc..229b6351a2 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -32,7 +32,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 51; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 120; + private static final long CARD_CONTENT_VERSION = 122; private Dao cardDao; private Set classNames; From 7cf78fb315fcb7ca8340c7e5f2bfe33b35c995ef Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 2 Oct 2018 21:02:22 +0400 Subject: [PATCH 005/167] * Fixed that some cards don't use multiple images in Alliances (ALL) and Homelands (HML); --- Mage.Sets/src/mage/sets/Alliances.java | 21 +++++++++++---------- Mage.Sets/src/mage/sets/Homelands.java | 5 +++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index 1553e50b59..e53b14b61d 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -23,6 +23,7 @@ public final class Alliances extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Aesthir Glider", "116a", Rarity.COMMON, mage.cards.a.AesthirGlider.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aesthir Glider", "116b", Rarity.COMMON, mage.cards.a.AesthirGlider.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Agent of Stromgald", "64a", Rarity.COMMON, mage.cards.a.AgentOfStromgald.class, NON_FULL_USE_VARIOUS)); @@ -67,12 +68,12 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("False Demise", "27b", Rarity.COMMON, mage.cards.f.FalseDemise.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Feast or Famine", "49a", Rarity.COMMON, mage.cards.f.FeastOrFamine.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Feast or Famine", "49b", Rarity.COMMON, mage.cards.f.FeastOrFamine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Fevered Strength", "50a", Rarity.COMMON, mage.cards.f.FeveredStrength.class)); - cards.add(new SetCardInfo("Fevered Strength", "50b", Rarity.COMMON, mage.cards.f.FeveredStrength.class)); + cards.add(new SetCardInfo("Fevered Strength", "50a", Rarity.COMMON, mage.cards.f.FeveredStrength.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fevered Strength", "50b", Rarity.COMMON, mage.cards.f.FeveredStrength.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Floodwater Dam", 119, Rarity.RARE, mage.cards.f.FloodwaterDam.class)); cards.add(new SetCardInfo("Force of Will", 28, Rarity.UNCOMMON, mage.cards.f.ForceOfWill.class)); - cards.add(new SetCardInfo("Foresight", "29a", Rarity.COMMON, mage.cards.f.Foresight.class)); - cards.add(new SetCardInfo("Foresight", "29b", Rarity.COMMON, mage.cards.f.Foresight.class)); + cards.add(new SetCardInfo("Foresight", "29a", Rarity.COMMON, mage.cards.f.Foresight.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Foresight", "29b", Rarity.COMMON, mage.cards.f.Foresight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gorilla Berserkers", "93a", Rarity.COMMON, mage.cards.g.GorillaBerserkers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gorilla Berserkers", "93b", Rarity.COMMON, mage.cards.g.GorillaBerserkers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gorilla Chieftain", "94a", Rarity.COMMON, mage.cards.g.GorillaChieftain.class, NON_FULL_USE_VARIOUS)); @@ -100,8 +101,8 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Krovikan Horror", 53, Rarity.RARE, mage.cards.k.KrovikanHorror.class)); cards.add(new SetCardInfo("Krovikan Plague", 54, Rarity.UNCOMMON, mage.cards.k.KrovikanPlague.class)); cards.add(new SetCardInfo("Lake of the Dead", 140, Rarity.RARE, mage.cards.l.LakeOfTheDead.class)); - cards.add(new SetCardInfo("Lat-Nam's Legacy", "30a", Rarity.COMMON, mage.cards.l.LatNamsLegacy.class)); - cards.add(new SetCardInfo("Lat-Nam's Legacy", "30b", Rarity.COMMON, mage.cards.l.LatNamsLegacy.class)); + cards.add(new SetCardInfo("Lat-Nam's Legacy", "30a", Rarity.COMMON, mage.cards.l.LatNamsLegacy.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Lat-Nam's Legacy", "30b", Rarity.COMMON, mage.cards.l.LatNamsLegacy.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Library of Lat-Nam", 31, Rarity.RARE, mage.cards.l.LibraryOfLatNam.class)); cards.add(new SetCardInfo("Lim-Dul's High Guard", "55a", Rarity.COMMON, mage.cards.l.LimDulsHighGuard.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lim-Dul's High Guard", "55b", Rarity.COMMON, mage.cards.l.LimDulsHighGuard.class, NON_FULL_USE_VARIOUS)); @@ -136,8 +137,8 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Reprisal", "13b", Rarity.COMMON, mage.cards.r.Reprisal.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ritual of the Machine", 59, Rarity.RARE, mage.cards.r.RitualOfTheMachine.class)); cards.add(new SetCardInfo("Royal Decree", 14, Rarity.RARE, mage.cards.r.RoyalDecree.class)); - cards.add(new SetCardInfo("Royal Herbalist", "15a", Rarity.COMMON, mage.cards.r.RoyalHerbalist.class)); - cards.add(new SetCardInfo("Royal Herbalist", "15b", Rarity.COMMON, mage.cards.r.RoyalHerbalist.class)); + cards.add(new SetCardInfo("Royal Herbalist", "15a", Rarity.COMMON, mage.cards.r.RoyalHerbalist.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Royal Herbalist", "15b", Rarity.COMMON, mage.cards.r.RoyalHerbalist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("School of the Unseen", 141, Rarity.UNCOMMON, mage.cards.s.SchoolOfTheUnseen.class)); cards.add(new SetCardInfo("Seasoned Tactician", 17, Rarity.UNCOMMON, mage.cards.s.SeasonedTactician.class)); cards.add(new SetCardInfo("Sheltered Valley", 142, Rarity.RARE, mage.cards.s.ShelteredValley.class)); @@ -159,8 +160,8 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Storm Cauldron", 134, Rarity.RARE, mage.cards.s.StormCauldron.class)); cards.add(new SetCardInfo("Storm Crow", "36a", Rarity.COMMON, mage.cards.s.StormCrow.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Storm Crow", "36b", Rarity.COMMON, mage.cards.s.StormCrow.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Storm Shaman", "81a", Rarity.COMMON, mage.cards.s.StormShaman.class)); - cards.add(new SetCardInfo("Storm Shaman", "81b", Rarity.COMMON, mage.cards.s.StormShaman.class)); + cards.add(new SetCardInfo("Storm Shaman", "81a", Rarity.COMMON, mage.cards.s.StormShaman.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Storm Shaman", "81b", Rarity.COMMON, mage.cards.s.StormShaman.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Stromgald Spy", 62, Rarity.UNCOMMON, mage.cards.s.StromgaldSpy.class)); cards.add(new SetCardInfo("Surge of Strength", 109, Rarity.UNCOMMON, mage.cards.s.SurgeOfStrength.class)); cards.add(new SetCardInfo("Sustaining Spirit", 18, Rarity.RARE, mage.cards.s.SustainingSpirit.class)); diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index 3d9b71f53b..beb34c641f 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -17,7 +17,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class Homelands extends ExpansionSet { @@ -37,6 +36,7 @@ public final class Homelands extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abbey Gargoyles", 1, Rarity.UNCOMMON, mage.cards.a.AbbeyGargoyles.class)); cards.add(new SetCardInfo("Abbey Matron", "2a", Rarity.COMMON, AbbeyMatron.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Abbey Matron", "2b", Rarity.COMMON, AbbeyMatron.class, NON_FULL_USE_VARIOUS)); @@ -122,7 +122,8 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Joven's Tools", 108, Rarity.UNCOMMON, mage.cards.j.JovensTools.class)); cards.add(new SetCardInfo("Koskun Falls", 55, Rarity.RARE, mage.cards.k.KoskunFalls.class)); cards.add(new SetCardInfo("Koskun Keep", 114, Rarity.UNCOMMON, mage.cards.k.KoskunKeep.class)); - cards.add(new SetCardInfo("Labyrinth Minotaur", "30a", Rarity.COMMON, mage.cards.l.LabyrinthMinotaur.class)); + cards.add(new SetCardInfo("Labyrinth Minotaur", "30a", Rarity.COMMON, mage.cards.l.LabyrinthMinotaur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Labyrinth Minotaur", "30b", Rarity.COMMON, mage.cards.l.LabyrinthMinotaur.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Leaping Lizard", 90, Rarity.COMMON, mage.cards.l.LeapingLizard.class)); cards.add(new SetCardInfo("Leeches", 9, Rarity.RARE, mage.cards.l.Leeches.class)); cards.add(new SetCardInfo("Mammoth Harness", 91, Rarity.RARE, mage.cards.m.MammothHarness.class)); From 16d4639846706ccc17fb575c5c0b3134e753eec0 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 2 Oct 2018 21:49:26 +0400 Subject: [PATCH 006/167] * Fixed Battlebond (BBD) booster that it missing of land card; --- Mage.Sets/src/mage/sets/Battlebond.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 3c13280af4..3bbc82b5d0 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -20,11 +20,11 @@ public final class Battlebond extends ExpansionSet { private Battlebond() { super("Battlebond", "BBD", ExpansionSet.buildDate(2018, 6, 8), SetType.SUPPLEMENTAL); this.blockName = "Battlebond"; - this.hasBasicLands = false; + this.hasBasicLands = true; this.hasBoosters = true; this.hasPartnerMechanic = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; + this.numBoosterLands = 1; + this.numBoosterCommon = 10; this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; From 63937351c1c595482c13cd00f48db756173acd92 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 2 Oct 2018 22:03:50 +0400 Subject: [PATCH 007/167] * Fixed Coldsnap (CSP) booster that it missing of land card; --- Mage.Sets/src/mage/sets/Coldsnap.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index 21790372da..67274220f8 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class Coldsnap extends ExpansionSet { @@ -21,13 +20,14 @@ public final class Coldsnap extends ExpansionSet { super("Coldsnap", "CSP", ExpansionSet.buildDate(2006, 6, 21), SetType.EXPANSION); this.blockName = "Ice Age"; this.hasBoosters = true; - this.numBoosterLands = 0; + this.numBoosterLands = 1; this.numBoosterCommon = 11; this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; this.parentSet = IceAge.getInstance(); - this.hasBasicLands = false; + this.hasBasicLands = true; + cards.add(new SetCardInfo("Adarkar Valkyrie", 1, Rarity.RARE, mage.cards.a.AdarkarValkyrie.class)); cards.add(new SetCardInfo("Adarkar Windform", 26, Rarity.UNCOMMON, mage.cards.a.AdarkarWindform.class)); cards.add(new SetCardInfo("Allosaurus Rider", 101, Rarity.RARE, mage.cards.a.AllosaurusRider.class)); From 434044eb0f23b5a3766d00d4f7bed476d71d85c2 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 00:45:58 +0400 Subject: [PATCH 008/167] * Fixed missing lands from some sets in lands/decks generation; --- Mage.Sets/src/mage/sets/ArabianNights.java | 4 ++-- Mage.Sets/src/mage/sets/Champs.java | 3 ++- Mage.Sets/src/mage/sets/CommanderAnthology.java | 2 +- Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java | 2 +- Mage.Sets/src/mage/sets/CommandersArsenal.java | 3 ++- Mage.Sets/src/mage/sets/DuelDecksAjaniVsNicolBolas.java | 4 ++-- .../src/mage/sets/DuelDecksAnthologyDivineVsDemonic.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksAnthologyElvesVsGoblins.java | 4 ++-- .../src/mage/sets/DuelDecksAnthologyGarrukVsLiliana.java | 4 ++-- Mage.Sets/src/mage/sets/DuelDecksAnthologyJaceVsChandra.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksBlessedVsCursed.java | 4 ++-- Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksElspethVsTezzeret.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksElvesVsGoblins.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksGarrukVsLiliana.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksHeroesVsMonsters.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksIzzetVsGolgari.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksJaceVsVraska.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksKnightsVsDragons.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksMindVsMight.java | 3 +-- Mage.Sets/src/mage/sets/DuelDecksNissaVsObNixilis.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksPhyrexiaVsTheCoalition.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksSorinVsTibalt.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksSpeedVsCunning.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksVenserVsKoth.java | 2 +- Mage.Sets/src/mage/sets/DuelDecksZendikarVsEldrazi.java | 2 +- Mage.Sets/src/mage/sets/EighthEdition.java | 1 + Mage.Sets/src/mage/sets/EighthEditionBox.java | 3 +++ Mage.Sets/src/mage/sets/ExplorersOfIxalan.java | 2 +- Mage.Sets/src/mage/sets/FateReforged.java | 4 ++-- Mage.Sets/src/mage/sets/GrandPrixPromos.java | 2 +- Mage.Sets/src/mage/sets/HASCONPromo2017.java | 3 ++- Mage.Sets/src/mage/sets/HappyHolidays.java | 2 +- Mage.Sets/src/mage/sets/MastersEditionII.java | 4 ++-- Mage.Sets/src/mage/sets/NinthEditionBox.java | 1 + Mage.Sets/src/mage/sets/OathOfTheGatewatch.java | 3 +-- .../src/mage/sets/PremiumDeckSeriesFireAndLightning.java | 2 +- Mage.Sets/src/mage/sets/PremiumDeckSeriesGraveborn.java | 2 +- Mage.Sets/src/mage/sets/PremiumDeckSeriesSlivers.java | 2 +- Mage.Sets/src/mage/sets/PrereleaseEvents.java | 3 ++- Mage.Sets/src/mage/sets/RivalsOfIxalan.java | 3 +-- Mage.Sets/src/mage/sets/SuperSeries.java | 3 ++- Mage.Sets/src/mage/sets/UginsFate.java | 3 ++- Mage/src/main/java/mage/cards/ExpansionSet.java | 3 +++ 47 files changed, 64 insertions(+), 53 deletions(-) diff --git a/Mage.Sets/src/mage/sets/ArabianNights.java b/Mage.Sets/src/mage/sets/ArabianNights.java index 7776d5f2bb..ecca8e9ec7 100644 --- a/Mage.Sets/src/mage/sets/ArabianNights.java +++ b/Mage.Sets/src/mage/sets/ArabianNights.java @@ -13,7 +13,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class ArabianNights extends ExpansionSet { @@ -26,13 +25,14 @@ public final class ArabianNights extends ExpansionSet { private ArabianNights() { super("Arabian Nights", "ARN", ExpansionSet.buildDate(1993, 11, 1), SetType.EXPANSION); - this.hasBasicLands = false; + this.hasBasicLands = true; this.hasBoosters = true; this.numBoosterLands = 1; this.numBoosterCommon = 10; this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abu Ja'far", 1, Rarity.UNCOMMON, mage.cards.a.AbuJafar.class)); cards.add(new SetCardInfo("Aladdin", 34, Rarity.RARE, mage.cards.a.Aladdin.class)); cards.add(new SetCardInfo("Aladdin's Lamp", 56, Rarity.RARE, mage.cards.a.AladdinsLamp.class)); diff --git a/Mage.Sets/src/mage/sets/Champs.java b/Mage.Sets/src/mage/sets/Champs.java index 63e03751e0..f748aa9a94 100644 --- a/Mage.Sets/src/mage/sets/Champs.java +++ b/Mage.Sets/src/mage/sets/Champs.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class Champs extends ExpansionSet { @@ -20,6 +19,8 @@ public final class Champs extends ExpansionSet { private Champs() { super("Champs", "CP", ExpansionSet.buildDate(2006, 3, 18), SetType.PROMOTIONAL); this.hasBoosters = false; + this.hasBasicLands = false; + cards.add(new SetCardInfo("Blood Knight", 7, Rarity.SPECIAL, mage.cards.b.BloodKnight.class)); cards.add(new SetCardInfo("Bramblewood Paragon", 11, Rarity.SPECIAL, mage.cards.b.BramblewoodParagon.class)); cards.add(new SetCardInfo("Doran, the Siege Tower", 10, Rarity.SPECIAL, mage.cards.d.DoranTheSiegeTower.class)); diff --git a/Mage.Sets/src/mage/sets/CommanderAnthology.java b/Mage.Sets/src/mage/sets/CommanderAnthology.java index d76f9b2082..fdc452bb04 100644 --- a/Mage.Sets/src/mage/sets/CommanderAnthology.java +++ b/Mage.Sets/src/mage/sets/CommanderAnthology.java @@ -18,7 +18,7 @@ public final class CommanderAnthology extends ExpansionSet { private CommanderAnthology() { super("Commander Anthology", "CMA", ExpansionSet.buildDate(2017, 6, 9), SetType.SUPPLEMENTAL); this.blockName = "Command Zone"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Acidic Slime", 90, Rarity.UNCOMMON, mage.cards.a.AcidicSlime.class)); cards.add(new SetCardInfo("Aerie Mystics", 1, Rarity.UNCOMMON, mage.cards.a.AerieMystics.class)); diff --git a/Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java b/Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java index 748f04f533..1d0d7240e3 100644 --- a/Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java +++ b/Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java @@ -18,7 +18,7 @@ public class CommanderAnthologyVolumeII extends ExpansionSet { private CommanderAnthologyVolumeII() { super("Commander Anthology Volume II", "CM2", ExpansionSet.buildDate(2018, 6, 8), SetType.SUPPLEMENTAL); this.blockName = "Command Zone"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Abzan Falconer", 15, Rarity.UNCOMMON, mage.cards.a.AbzanFalconer.class)); cards.add(new SetCardInfo("Acidic Slime", 132, Rarity.UNCOMMON, mage.cards.a.AcidicSlime.class)); diff --git a/Mage.Sets/src/mage/sets/CommandersArsenal.java b/Mage.Sets/src/mage/sets/CommandersArsenal.java index f83095a8d3..aa1943bce2 100644 --- a/Mage.Sets/src/mage/sets/CommandersArsenal.java +++ b/Mage.Sets/src/mage/sets/CommandersArsenal.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class CommandersArsenal extends ExpansionSet { @@ -20,6 +19,8 @@ public final class CommandersArsenal extends ExpansionSet { private CommandersArsenal() { super("Commander's Arsenal", "CM1", ExpansionSet.buildDate(2012, 11, 2), SetType.SUPPLEMENTAL); this.blockName = "Command Zone"; + this.hasBasicLands = false; + cards.add(new SetCardInfo("Chaos Warp", 1, Rarity.RARE, mage.cards.c.ChaosWarp.class)); cards.add(new SetCardInfo("Command Tower", 2, Rarity.COMMON, mage.cards.c.CommandTower.class)); cards.add(new SetCardInfo("Decree of Pain", 3, Rarity.RARE, mage.cards.d.DecreeOfPain.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksAjaniVsNicolBolas.java b/Mage.Sets/src/mage/sets/DuelDecksAjaniVsNicolBolas.java index d45057ed6f..d0cd95b426 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksAjaniVsNicolBolas.java +++ b/Mage.Sets/src/mage/sets/DuelDecksAjaniVsNicolBolas.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author LevelX2 */ public final class DuelDecksAjaniVsNicolBolas extends ExpansionSet { @@ -20,7 +19,8 @@ public final class DuelDecksAjaniVsNicolBolas extends ExpansionSet { private DuelDecksAjaniVsNicolBolas() { super("Duel Decks: Ajani vs. Nicol Bolas", "DDH", ExpansionSet.buildDate(2011, 9, 2), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; + cards.add(new SetCardInfo("Ageless Entity", 18, Rarity.RARE, mage.cards.a.AgelessEntity.class)); cards.add(new SetCardInfo("Agonizing Demise", 66, Rarity.COMMON, mage.cards.a.AgonizingDemise.class)); cards.add(new SetCardInfo("Ajani's Mantra", 22, Rarity.COMMON, mage.cards.a.AjanisMantra.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksAnthologyDivineVsDemonic.java b/Mage.Sets/src/mage/sets/DuelDecksAnthologyDivineVsDemonic.java index f42dd7ce48..c7ac43ed64 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksAnthologyDivineVsDemonic.java +++ b/Mage.Sets/src/mage/sets/DuelDecksAnthologyDivineVsDemonic.java @@ -19,7 +19,7 @@ public final class DuelDecksAnthologyDivineVsDemonic extends ExpansionSet { super("Duel Decks: Anthology, Divine vs. Demonic", "DD3DVD", ExpansionSet.buildDate(2014, 12, 5), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks: Anthology"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Abyssal Gatekeeper", 31, Rarity.COMMON, mage.cards.a.AbyssalGatekeeper.class)); cards.add(new SetCardInfo("Abyssal Specter", 40, Rarity.UNCOMMON, mage.cards.a.AbyssalSpecter.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksAnthologyElvesVsGoblins.java b/Mage.Sets/src/mage/sets/DuelDecksAnthologyElvesVsGoblins.java index 6da2029429..90d7b15003 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksAnthologyElvesVsGoblins.java +++ b/Mage.Sets/src/mage/sets/DuelDecksAnthologyElvesVsGoblins.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class DuelDecksAnthologyElvesVsGoblins extends ExpansionSet { @@ -21,7 +20,8 @@ public final class DuelDecksAnthologyElvesVsGoblins extends ExpansionSet { super("Duel Decks: Anthology, Elves vs. Goblins", "DD3EVG", ExpansionSet.buildDate(2014, 12, 5), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks: Anthology"; - this.hasBasicLands = false; + this.hasBasicLands = true; + cards.add(new SetCardInfo("Akki Coalflinger", 33, Rarity.UNCOMMON, mage.cards.a.AkkiCoalflinger.class)); cards.add(new SetCardInfo("Allosaurus Rider", 2, Rarity.RARE, mage.cards.a.AllosaurusRider.class)); cards.add(new SetCardInfo("Ambush Commander", 1, Rarity.RARE, mage.cards.a.AmbushCommander.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksAnthologyGarrukVsLiliana.java b/Mage.Sets/src/mage/sets/DuelDecksAnthologyGarrukVsLiliana.java index 2671bec599..82154d1beb 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksAnthologyGarrukVsLiliana.java +++ b/Mage.Sets/src/mage/sets/DuelDecksAnthologyGarrukVsLiliana.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class DuelDecksAnthologyGarrukVsLiliana extends ExpansionSet { @@ -21,7 +20,8 @@ public final class DuelDecksAnthologyGarrukVsLiliana extends ExpansionSet { super("Duel Decks: Anthology, Garruk vs. Liliana", "DD3GVL", ExpansionSet.buildDate(2014, 12, 5), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks: Anthology"; - this.hasBasicLands = false; + this.hasBasicLands = true; + cards.add(new SetCardInfo("Albino Troll", 3, Rarity.UNCOMMON, mage.cards.a.AlbinoTroll.class)); cards.add(new SetCardInfo("Bad Moon", 48, Rarity.RARE, mage.cards.b.BadMoon.class)); cards.add(new SetCardInfo("Basking Rootwalla", 2, Rarity.COMMON, mage.cards.b.BaskingRootwalla.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksAnthologyJaceVsChandra.java b/Mage.Sets/src/mage/sets/DuelDecksAnthologyJaceVsChandra.java index dd1454bfe0..d75ab380ee 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksAnthologyJaceVsChandra.java +++ b/Mage.Sets/src/mage/sets/DuelDecksAnthologyJaceVsChandra.java @@ -20,7 +20,7 @@ public final class DuelDecksAnthologyJaceVsChandra extends ExpansionSet { super("Duel Decks: Anthology, Jace vs. Chandra", "DD3JVC", ExpansionSet.buildDate(2014, 12, 5), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks: Anthology"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Aethersnipe", 17, Rarity.COMMON, mage.cards.a.Aethersnipe.class)); cards.add(new SetCardInfo("Air Elemental", 13, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksBlessedVsCursed.java b/Mage.Sets/src/mage/sets/DuelDecksBlessedVsCursed.java index 3ecad9f7b8..2d318dce41 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksBlessedVsCursed.java +++ b/Mage.Sets/src/mage/sets/DuelDecksBlessedVsCursed.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class DuelDecksBlessedVsCursed extends ExpansionSet { @@ -20,7 +19,8 @@ public final class DuelDecksBlessedVsCursed extends ExpansionSet { private DuelDecksBlessedVsCursed() { super("Duel Decks: Blessed vs. Cursed", "DDQ", ExpansionSet.buildDate(2016, 2, 26), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; + cards.add(new SetCardInfo("Abattoir Ghoul", 50, Rarity.UNCOMMON, mage.cards.a.AbattoirGhoul.class)); cards.add(new SetCardInfo("Appetite for Brains", 51, Rarity.UNCOMMON, mage.cards.a.AppetiteForBrains.class)); cards.add(new SetCardInfo("Barter in Blood", 52, Rarity.UNCOMMON, mage.cards.b.BarterInBlood.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java b/Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java index 16f37617aa..9ea0082a56 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java +++ b/Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java @@ -18,7 +18,7 @@ public final class DuelDecksDivineVsDemonic extends ExpansionSet { private DuelDecksDivineVsDemonic() { super("Duel Decks: Divine vs. Demonic", "DDC", ExpansionSet.buildDate(2009, 04, 10), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Abyssal Gatekeeper", 31, Rarity.COMMON, mage.cards.a.AbyssalGatekeeper.class)); cards.add(new SetCardInfo("Abyssal Specter", 40, Rarity.UNCOMMON, mage.cards.a.AbyssalSpecter.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java b/Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java index 28e7c01358..0bc7d7758f 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java +++ b/Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java @@ -20,7 +20,7 @@ public final class DuelDecksElspethVsKiora extends ExpansionSet { private DuelDecksElspethVsKiora() { super("Duel Decks: Elspeth vs. Kiora", "DDO", ExpansionSet.buildDate(2015, 2, 27), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Accumulated Knowledge", 35, Rarity.COMMON, mage.cards.a.AccumulatedKnowledge.class)); cards.add(new SetCardInfo("Aetherize", 36, Rarity.UNCOMMON, mage.cards.a.Aetherize.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksElspethVsTezzeret.java b/Mage.Sets/src/mage/sets/DuelDecksElspethVsTezzeret.java index 427978c1db..a5f17614a9 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksElspethVsTezzeret.java +++ b/Mage.Sets/src/mage/sets/DuelDecksElspethVsTezzeret.java @@ -15,7 +15,7 @@ public final class DuelDecksElspethVsTezzeret extends ExpansionSet { private DuelDecksElspethVsTezzeret() { super("Duel Decks: Elspeth vs. Tezzeret", "DDF", ExpansionSet.buildDate(2010, 8, 3), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Abolish", 29, Rarity.UNCOMMON, mage.cards.a.Abolish.class)); cards.add(new SetCardInfo("Aether Spellbomb", 61, Rarity.COMMON, mage.cards.a.AetherSpellbomb.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksElvesVsGoblins.java b/Mage.Sets/src/mage/sets/DuelDecksElvesVsGoblins.java index 086c78f695..b86f603869 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksElvesVsGoblins.java +++ b/Mage.Sets/src/mage/sets/DuelDecksElvesVsGoblins.java @@ -18,7 +18,7 @@ public final class DuelDecksElvesVsGoblins extends ExpansionSet { private DuelDecksElvesVsGoblins() { super("Duel Decks: Elves vs. Goblins", "EVG", ExpansionSet.buildDate(2007, 11, 16), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Akki Coalflinger", 33, Rarity.UNCOMMON, mage.cards.a.AkkiCoalflinger.class)); cards.add(new SetCardInfo("Allosaurus Rider", 2, Rarity.RARE, mage.cards.a.AllosaurusRider.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksGarrukVsLiliana.java b/Mage.Sets/src/mage/sets/DuelDecksGarrukVsLiliana.java index 784b1a1b27..ec381e2950 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksGarrukVsLiliana.java +++ b/Mage.Sets/src/mage/sets/DuelDecksGarrukVsLiliana.java @@ -23,7 +23,7 @@ public final class DuelDecksGarrukVsLiliana extends ExpansionSet { private DuelDecksGarrukVsLiliana() { super("Duel Decks: Garruk vs. Liliana", "DDD", ExpansionSet.buildDate(2009, 10, 30), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Albino Troll", 3, Rarity.UNCOMMON, mage.cards.a.AlbinoTroll.class)); cards.add(new SetCardInfo("Bad Moon", 48, Rarity.RARE, mage.cards.b.BadMoon.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksHeroesVsMonsters.java b/Mage.Sets/src/mage/sets/DuelDecksHeroesVsMonsters.java index d629798273..b82b65316d 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksHeroesVsMonsters.java +++ b/Mage.Sets/src/mage/sets/DuelDecksHeroesVsMonsters.java @@ -19,7 +19,7 @@ public final class DuelDecksHeroesVsMonsters extends ExpansionSet { private DuelDecksHeroesVsMonsters() { super("Duel Decks: Heroes vs. Monsters", "DDL", ExpansionSet.buildDate(2013, 9, 6), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Anax and Cymede", 11, Rarity.RARE, mage.cards.a.AnaxAndCymede.class)); cards.add(new SetCardInfo("Armory Guard", 12, Rarity.COMMON, mage.cards.a.ArmoryGuard.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksIzzetVsGolgari.java b/Mage.Sets/src/mage/sets/DuelDecksIzzetVsGolgari.java index be47d4f994..aaa55c3528 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksIzzetVsGolgari.java +++ b/Mage.Sets/src/mage/sets/DuelDecksIzzetVsGolgari.java @@ -19,7 +19,7 @@ public final class DuelDecksIzzetVsGolgari extends ExpansionSet { private DuelDecksIzzetVsGolgari() { super("Duel Decks: Izzet vs. Golgari", "DDJ", ExpansionSet.buildDate(2012, 9, 7), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Barren Moor", 78, Rarity.COMMON, mage.cards.b.BarrenMoor.class)); cards.add(new SetCardInfo("Boneyard Wurm", 51, Rarity.UNCOMMON, mage.cards.b.BoneyardWurm.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java b/Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java index 4e1e9fde86..ba925a659d 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java +++ b/Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java @@ -23,7 +23,7 @@ public final class DuelDecksJaceVsChandra extends ExpansionSet { private DuelDecksJaceVsChandra() { super("Duel Decks: Jace vs. Chandra", "DD2", ExpansionSet.buildDate(2008, 11, 07), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Aethersnipe", 17, Rarity.COMMON, mage.cards.a.Aethersnipe.class)); cards.add(new SetCardInfo("Air Elemental", 13, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksJaceVsVraska.java b/Mage.Sets/src/mage/sets/DuelDecksJaceVsVraska.java index ace1a7b25e..877cb61516 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksJaceVsVraska.java +++ b/Mage.Sets/src/mage/sets/DuelDecksJaceVsVraska.java @@ -19,7 +19,7 @@ public final class DuelDecksJaceVsVraska extends ExpansionSet { private DuelDecksJaceVsVraska() { super("Duel Decks: Jace vs. Vraska", "DDM", ExpansionSet.buildDate(2014, 3, 14), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Acidic Slime", 64, Rarity.UNCOMMON, mage.cards.a.AcidicSlime.class)); cards.add(new SetCardInfo("Aeon Chronicler", 17, Rarity.RARE, mage.cards.a.AeonChronicler.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksKnightsVsDragons.java b/Mage.Sets/src/mage/sets/DuelDecksKnightsVsDragons.java index 560412869e..a62a30a834 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksKnightsVsDragons.java +++ b/Mage.Sets/src/mage/sets/DuelDecksKnightsVsDragons.java @@ -19,7 +19,7 @@ public final class DuelDecksKnightsVsDragons extends ExpansionSet { private DuelDecksKnightsVsDragons() { super("Duel Decks: Knights vs. Dragons", "DDG", ExpansionSet.buildDate(2011, 4, 1), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Alaborn Cavalier", 18, Rarity.UNCOMMON, mage.cards.a.AlabornCavalier.class)); cards.add(new SetCardInfo("Armillary Sphere", 62, Rarity.COMMON, mage.cards.a.ArmillarySphere.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java b/Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java index 564fabb3d1..ee9d989903 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java +++ b/Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java @@ -19,7 +19,7 @@ public final class DuelDecksMerfolkVsGoblins extends ExpansionSet { private DuelDecksMerfolkVsGoblins() { super("Duel Decks: Merfolk vs. Goblins", "DDT", ExpansionSet.buildDate(2017, 11, 10), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Aquitect's Will", 2, Rarity.COMMON, mage.cards.a.AquitectsWill.class)); cards.add(new SetCardInfo("Battle Squadron", 33, Rarity.UNCOMMON, mage.cards.b.BattleSquadron.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksMindVsMight.java b/Mage.Sets/src/mage/sets/DuelDecksMindVsMight.java index 4745ee10b4..cab524d124 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksMindVsMight.java +++ b/Mage.Sets/src/mage/sets/DuelDecksMindVsMight.java @@ -5,7 +5,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class DuelDecksMindVsMight extends ExpansionSet { @@ -19,7 +18,7 @@ public final class DuelDecksMindVsMight extends ExpansionSet { private DuelDecksMindVsMight() { super("Duel Decks: Mind vs. Might", "DDS", ExpansionSet.buildDate(2017, 3, 31), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Ambassador Oak", 42, Rarity.COMMON, mage.cards.a.AmbassadorOak.class)); cards.add(new SetCardInfo("Beacon of Destruction", 35, Rarity.RARE, mage.cards.b.BeaconOfDestruction.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksNissaVsObNixilis.java b/Mage.Sets/src/mage/sets/DuelDecksNissaVsObNixilis.java index f05caa644c..aee53972a3 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksNissaVsObNixilis.java +++ b/Mage.Sets/src/mage/sets/DuelDecksNissaVsObNixilis.java @@ -18,7 +18,7 @@ public final class DuelDecksNissaVsObNixilis extends ExpansionSet { private DuelDecksNissaVsObNixilis() { super("Duel Decks: Nissa vs. Ob Nixilis", "DDR", ExpansionSet.buildDate(2016, 9, 2), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Abundance", 2, Rarity.RARE, mage.cards.a.Abundance.class)); cards.add(new SetCardInfo("Altar's Reap", 37, Rarity.COMMON, mage.cards.a.AltarsReap.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksPhyrexiaVsTheCoalition.java b/Mage.Sets/src/mage/sets/DuelDecksPhyrexiaVsTheCoalition.java index 9ceb369deb..44f120822d 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksPhyrexiaVsTheCoalition.java +++ b/Mage.Sets/src/mage/sets/DuelDecksPhyrexiaVsTheCoalition.java @@ -20,7 +20,7 @@ public final class DuelDecksPhyrexiaVsTheCoalition extends ExpansionSet { super("Duel Decks: Phyrexia vs. the Coalition", "DDE", ExpansionSet.buildDate(2010, 3, 19), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Allied Strategies", 63, Rarity.UNCOMMON, mage.cards.a.AlliedStrategies.class)); cards.add(new SetCardInfo("Armadillo Cloak", 58, Rarity.COMMON, mage.cards.a.ArmadilloCloak.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksSorinVsTibalt.java b/Mage.Sets/src/mage/sets/DuelDecksSorinVsTibalt.java index 8267b5151e..4892991ab2 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksSorinVsTibalt.java +++ b/Mage.Sets/src/mage/sets/DuelDecksSorinVsTibalt.java @@ -19,7 +19,7 @@ public final class DuelDecksSorinVsTibalt extends ExpansionSet { private DuelDecksSorinVsTibalt() { super("Duel Decks: Sorin vs. Tibalt", "DDK", ExpansionSet.buildDate(2013, 3, 15), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Absorb Vis", 31, Rarity.COMMON, mage.cards.a.AbsorbVis.class)); cards.add(new SetCardInfo("Akoum Refuge", 73, Rarity.UNCOMMON, mage.cards.a.AkoumRefuge.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksSpeedVsCunning.java b/Mage.Sets/src/mage/sets/DuelDecksSpeedVsCunning.java index 7f41ae0973..4391b258fa 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksSpeedVsCunning.java +++ b/Mage.Sets/src/mage/sets/DuelDecksSpeedVsCunning.java @@ -19,7 +19,7 @@ public final class DuelDecksSpeedVsCunning extends ExpansionSet { private DuelDecksSpeedVsCunning() { super("Duel Decks: Speed vs. Cunning", "DDN", ExpansionSet.buildDate(2014, 9, 5), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Act of Treason", 26, Rarity.COMMON, mage.cards.a.ActOfTreason.class)); cards.add(new SetCardInfo("Aquamorph Entity", 54, Rarity.COMMON, mage.cards.a.AquamorphEntity.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksVenserVsKoth.java b/Mage.Sets/src/mage/sets/DuelDecksVenserVsKoth.java index cfab4d1272..0057b5c79e 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksVenserVsKoth.java +++ b/Mage.Sets/src/mage/sets/DuelDecksVenserVsKoth.java @@ -18,7 +18,7 @@ public final class DuelDecksVenserVsKoth extends ExpansionSet { private DuelDecksVenserVsKoth() { super("Duel Decks: Venser vs. Koth", "DDI", ExpansionSet.buildDate(2012, 3, 30), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Aether Membrane", 48, Rarity.UNCOMMON, mage.cards.a.AetherMembrane.class)); cards.add(new SetCardInfo("Angelic Shield", 27, Rarity.UNCOMMON, mage.cards.a.AngelicShield.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksZendikarVsEldrazi.java b/Mage.Sets/src/mage/sets/DuelDecksZendikarVsEldrazi.java index ca327a07f0..2ae4c83a9f 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksZendikarVsEldrazi.java +++ b/Mage.Sets/src/mage/sets/DuelDecksZendikarVsEldrazi.java @@ -18,7 +18,7 @@ public final class DuelDecksZendikarVsEldrazi extends ExpansionSet { private DuelDecksZendikarVsEldrazi() { super("Duel Decks: Zendikar vs. Eldrazi", "DDP", ExpansionSet.buildDate(2015, 8, 28), SetType.SUPPLEMENTAL); this.blockName = "Duel Decks"; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Affa Guard Hound", 2, Rarity.UNCOMMON, mage.cards.a.AffaGuardHound.class)); cards.add(new SetCardInfo("Akoum Refuge", 67, Rarity.UNCOMMON, mage.cards.a.AkoumRefuge.class)); diff --git a/Mage.Sets/src/mage/sets/EighthEdition.java b/Mage.Sets/src/mage/sets/EighthEdition.java index 79784eb062..3d235376c5 100644 --- a/Mage.Sets/src/mage/sets/EighthEdition.java +++ b/Mage.Sets/src/mage/sets/EighthEdition.java @@ -370,6 +370,7 @@ public final class EighthEdition extends ExpansionSet { cards.add(new SetCardInfo("Zombify", 174, Rarity.UNCOMMON, mage.cards.z.Zombify.class)); cards.add(new SetCardInfo("Zur's Weirding", 116, Rarity.RARE, mage.cards.z.ZursWeirding.class)); // 8ed Edition Box Set (we need to create own set) + // http://www.magiclibrarities.net/540-rarities-eighth-edition-box-set-cards-english-cards-index.html // cards.add(new SetCardInfo("Eager Cadet", 1, Rarity.COMMON, mage.cards.e.EagerCadet.class)); // cards.add(new SetCardInfo("Vengeance", 2, Rarity.UNCOMMON, mage.cards.v.Vengeance.class)); // cards.add(new SetCardInfo("Sea Eagle", 4, Rarity.COMMON, mage.cards.s.SeaEagle.class)); diff --git a/Mage.Sets/src/mage/sets/EighthEditionBox.java b/Mage.Sets/src/mage/sets/EighthEditionBox.java index 05b7be001c..84cf11a524 100644 --- a/Mage.Sets/src/mage/sets/EighthEditionBox.java +++ b/Mage.Sets/src/mage/sets/EighthEditionBox.java @@ -15,6 +15,9 @@ public final class EighthEditionBox extends ExpansionSet { private EighthEditionBox() { super("EighthEditionBox", "8EB", ExpansionSet.buildDate(2003, 7, 28), SetType.CORE); this.hasBoosters = false; + this.hasBasicLands = false; + + // // http://www.magiclibrarities.net/540-rarities-eighth-edition-box-set-cards-english-cards-index.html cards.add(new SetCardInfo("Eager Cadet", 1, Rarity.COMMON, mage.cards.e.EagerCadet.class)); cards.add(new SetCardInfo("Vengeance", 2, Rarity.UNCOMMON, mage.cards.v.Vengeance.class)); cards.add(new SetCardInfo("Giant Octopus", 3, Rarity.COMMON, mage.cards.g.GiantOctopus.class)); diff --git a/Mage.Sets/src/mage/sets/ExplorersOfIxalan.java b/Mage.Sets/src/mage/sets/ExplorersOfIxalan.java index f6f8155799..220ca05dd2 100644 --- a/Mage.Sets/src/mage/sets/ExplorersOfIxalan.java +++ b/Mage.Sets/src/mage/sets/ExplorersOfIxalan.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author JayDi85 */ public final class ExplorersOfIxalan extends ExpansionSet { @@ -20,6 +19,7 @@ public final class ExplorersOfIxalan extends ExpansionSet { private ExplorersOfIxalan() { super("Explorers of Ixalan", "E02", ExpansionSet.buildDate(2017, 11, 24), SetType.SUPPLEMENTAL); this.blockName = "Explorers of Ixalan"; + this.hasBasicLands = false; cards.add(new SetCardInfo("Adaptive Automaton", 42, Rarity.RARE, mage.cards.a.AdaptiveAutomaton.class)); cards.add(new SetCardInfo("Aether Gale", 7, Rarity.RARE, mage.cards.a.AetherGale.class)); diff --git a/Mage.Sets/src/mage/sets/FateReforged.java b/Mage.Sets/src/mage/sets/FateReforged.java index 0cc077d3ed..f29b7d81b3 100644 --- a/Mage.Sets/src/mage/sets/FateReforged.java +++ b/Mage.Sets/src/mage/sets/FateReforged.java @@ -13,7 +13,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class FateReforged extends ExpansionSet { @@ -31,7 +30,7 @@ public final class FateReforged extends ExpansionSet { super("Fate Reforged", "FRF", ExpansionSet.buildDate(2015, 1, 23), SetType.EXPANSION); this.blockName = "Khans of Tarkir"; this.parentSet = KhansOfTarkir.getInstance(); - this.hasBasicLands = false; + this.hasBasicLands = true; this.hasBoosters = true; this.numBoosterSpecial = 1; this.numBoosterLands = 0; @@ -40,6 +39,7 @@ public final class FateReforged extends ExpansionSet { this.numBoosterRare = 1; this.numBoosterDoubleFaced = -1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Abzan Advantage", 2, Rarity.COMMON, mage.cards.a.AbzanAdvantage.class)); cards.add(new SetCardInfo("Abzan Beastmaster", 119, Rarity.UNCOMMON, mage.cards.a.AbzanBeastmaster.class)); cards.add(new SetCardInfo("Abzan Kin-Guard", 120, Rarity.UNCOMMON, mage.cards.a.AbzanKinGuard.class)); diff --git a/Mage.Sets/src/mage/sets/GrandPrixPromos.java b/Mage.Sets/src/mage/sets/GrandPrixPromos.java index 3ac1343093..b3362b716f 100644 --- a/Mage.Sets/src/mage/sets/GrandPrixPromos.java +++ b/Mage.Sets/src/mage/sets/GrandPrixPromos.java @@ -19,7 +19,7 @@ public final class GrandPrixPromos extends ExpansionSet { private GrandPrixPromos() { super("Grand Prix Promos", "GPX", ExpansionSet.buildDate(2011, 6, 17), SetType.PROMOTIONAL); this.hasBoosters = false; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("All Is Dust", "2013b", Rarity.RARE, mage.cards.a.AllIsDust.class)); cards.add(new SetCardInfo("Batterskull", 2014, Rarity.MYTHIC, mage.cards.b.Batterskull.class)); diff --git a/Mage.Sets/src/mage/sets/HASCONPromo2017.java b/Mage.Sets/src/mage/sets/HASCONPromo2017.java index 33f6937315..be06cda1e1 100644 --- a/Mage.Sets/src/mage/sets/HASCONPromo2017.java +++ b/Mage.Sets/src/mage/sets/HASCONPromo2017.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author Saga */ public final class HASCONPromo2017 extends ExpansionSet { @@ -19,6 +18,8 @@ public final class HASCONPromo2017 extends ExpansionSet { private HASCONPromo2017() { super("HASCON Promo 2017", "H17", ExpansionSet.buildDate(2017, 9, 8), SetType.JOKESET); + this.hasBasicLands = false; + cards.add(new ExpansionSet.SetCardInfo("Grimlock, Dinobot Leader", "1a", Rarity.MYTHIC, mage.cards.g.GrimlockDinobotLeader.class)); cards.add(new ExpansionSet.SetCardInfo("Grimlock, Ferocious King", "1b", Rarity.MYTHIC, mage.cards.g.GrimlockFerociousKing.class)); cards.add(new ExpansionSet.SetCardInfo("Sword of Dungeons & Dragons", 3, Rarity.MYTHIC, mage.cards.s.SwordOfDungeonsAndDragons.class)); diff --git a/Mage.Sets/src/mage/sets/HappyHolidays.java b/Mage.Sets/src/mage/sets/HappyHolidays.java index 5f335b3e99..43c27e50c7 100644 --- a/Mage.Sets/src/mage/sets/HappyHolidays.java +++ b/Mage.Sets/src/mage/sets/HappyHolidays.java @@ -5,7 +5,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author spjspj */ public final class HappyHolidays extends ExpansionSet { @@ -18,6 +17,7 @@ public final class HappyHolidays extends ExpansionSet { private HappyHolidays() { super("Happy Holidays", "HHO", ExpansionSet.buildDate(2006, 12, 31), SetType.JOKESET); + this.hasBasicLands = false; cards.add(new SetCardInfo("Fruitcake Elemental", 6, Rarity.RARE, mage.cards.f.FruitcakeElemental.class)); cards.add(new SetCardInfo("Season's Beatings", 9, Rarity.RARE, mage.cards.s.SeasonsBeatings.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index c3f9f8ffbf..4ffc5c6e5a 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -18,7 +18,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author LevelX2 */ public final class MastersEditionII extends ExpansionSet { @@ -31,13 +30,14 @@ public final class MastersEditionII extends ExpansionSet { private MastersEditionII() { super("Masters Edition II", "ME2", ExpansionSet.buildDate(2008, 9, 22), SetType.MAGIC_ONLINE); - this.hasBasicLands = false; + this.hasBasicLands = true; this.hasBoosters = true; this.numBoosterLands = 1; this.numBoosterCommon = 10; this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Aether Storm", 39, Rarity.UNCOMMON, mage.cards.a.AetherStorm.class)); cards.add(new SetCardInfo("Abbey Gargoyles", 1, Rarity.UNCOMMON, mage.cards.a.AbbeyGargoyles.class)); cards.add(new SetCardInfo("Adarkar Sentinel", 201, Rarity.COMMON, mage.cards.a.AdarkarSentinel.class)); diff --git a/Mage.Sets/src/mage/sets/NinthEditionBox.java b/Mage.Sets/src/mage/sets/NinthEditionBox.java index 10f11dfacc..06337351eb 100644 --- a/Mage.Sets/src/mage/sets/NinthEditionBox.java +++ b/Mage.Sets/src/mage/sets/NinthEditionBox.java @@ -15,6 +15,7 @@ public final class NinthEditionBox extends ExpansionSet { private NinthEditionBox() { super("Ninth Edition Box", "9EB", ExpansionSet.buildDate(2005, 7, 29), SetType.CORE); this.hasBoosters = false; + cards.add(new SetCardInfo("Coral Eel", 3, Rarity.COMMON, mage.cards.c.CoralEel.class)); cards.add(new SetCardInfo("Eager Cadet", 1, Rarity.COMMON, mage.cards.e.EagerCadet.class)); cards.add(new SetCardInfo("Enormous Baloth", 9, Rarity.UNCOMMON, mage.cards.e.EnormousBaloth.class)); diff --git a/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java b/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java index e99f121ea5..66ec171f85 100644 --- a/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java +++ b/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java @@ -17,7 +17,6 @@ import java.util.ArrayList; import java.util.List; /** - * * @author fireshoes */ public final class OathOfTheGatewatch extends ExpansionSet { @@ -35,7 +34,7 @@ public final class OathOfTheGatewatch extends ExpansionSet { this.blockName = "Battle for Zendikar"; this.parentSet = BattleForZendikar.getInstance(); this.hasBoosters = true; - this.hasBasicLands = false; + this.hasBasicLands = true; this.numBoosterLands = 1; this.numBoosterCommon = 10; this.numBoosterUncommon = 3; diff --git a/Mage.Sets/src/mage/sets/PremiumDeckSeriesFireAndLightning.java b/Mage.Sets/src/mage/sets/PremiumDeckSeriesFireAndLightning.java index 59ae252c74..ec04e84bdd 100644 --- a/Mage.Sets/src/mage/sets/PremiumDeckSeriesFireAndLightning.java +++ b/Mage.Sets/src/mage/sets/PremiumDeckSeriesFireAndLightning.java @@ -19,7 +19,7 @@ public final class PremiumDeckSeriesFireAndLightning extends ExpansionSet { private PremiumDeckSeriesFireAndLightning() { super("Premium Deck Series: Fire and Lightning", "PD2", ExpansionSet.buildDate(2010, 11, 1), SetType.SUPPLEMENTAL); - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Ball Lightning", 12, Rarity.RARE, mage.cards.b.BallLightning.class)); cards.add(new SetCardInfo("Barbarian Ring", 28, Rarity.UNCOMMON, mage.cards.b.BarbarianRing.class)); diff --git a/Mage.Sets/src/mage/sets/PremiumDeckSeriesGraveborn.java b/Mage.Sets/src/mage/sets/PremiumDeckSeriesGraveborn.java index 0cd7b2d1d9..35dcb39234 100644 --- a/Mage.Sets/src/mage/sets/PremiumDeckSeriesGraveborn.java +++ b/Mage.Sets/src/mage/sets/PremiumDeckSeriesGraveborn.java @@ -18,7 +18,7 @@ public final class PremiumDeckSeriesGraveborn extends ExpansionSet { private PremiumDeckSeriesGraveborn() { super("Premium Deck Series: Graveborn", "PD3", ExpansionSet.buildDate(2011, 11, 1), SetType.SUPPLEMENTAL); - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Animate Dead", 16, Rarity.UNCOMMON, mage.cards.a.AnimateDead.class)); cards.add(new SetCardInfo("Avatar of Woe", 6, Rarity.RARE, mage.cards.a.AvatarOfWoe.class)); diff --git a/Mage.Sets/src/mage/sets/PremiumDeckSeriesSlivers.java b/Mage.Sets/src/mage/sets/PremiumDeckSeriesSlivers.java index 9a0b0aa8ac..0dcd4dffc5 100644 --- a/Mage.Sets/src/mage/sets/PremiumDeckSeriesSlivers.java +++ b/Mage.Sets/src/mage/sets/PremiumDeckSeriesSlivers.java @@ -18,7 +18,7 @@ public final class PremiumDeckSeriesSlivers extends ExpansionSet { private PremiumDeckSeriesSlivers() { super("Premium Deck Series: Slivers", "H09", ExpansionSet.buildDate(2009, 11, 1), SetType.SUPPLEMENTAL); - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Acidic Sliver", 13, Rarity.UNCOMMON, mage.cards.a.AcidicSliver.class)); cards.add(new SetCardInfo("Amoeboid Changeling", 3, Rarity.COMMON, mage.cards.a.AmoeboidChangeling.class)); diff --git a/Mage.Sets/src/mage/sets/PrereleaseEvents.java b/Mage.Sets/src/mage/sets/PrereleaseEvents.java index 332dd771a6..7cd1605e9a 100644 --- a/Mage.Sets/src/mage/sets/PrereleaseEvents.java +++ b/Mage.Sets/src/mage/sets/PrereleaseEvents.java @@ -15,7 +15,8 @@ public final class PrereleaseEvents extends ExpansionSet { private PrereleaseEvents() { super("Prerelease Events", "PTC", ExpansionSet.buildDate(1990, 1, 1), SetType.PROMOTIONAL); this.hasBoosters = false; - this.hasBasicLands = false; + this.hasBasicLands = true; + cards.add(new SetCardInfo("Abbot of Keral Keep", 198, Rarity.RARE, mage.cards.a.AbbotOfKeralKeep.class)); cards.add(new SetCardInfo("Abhorrent Overlord", 70, Rarity.SPECIAL, mage.cards.a.AbhorrentOverlord.class)); cards.add(new SetCardInfo("Abzan Ascendancy", 88, Rarity.SPECIAL, mage.cards.a.AbzanAscendancy.class)); diff --git a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java index 54d76ef304..e0995645d6 100644 --- a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class RivalsOfIxalan extends ExpansionSet { @@ -22,7 +21,7 @@ public final class RivalsOfIxalan extends ExpansionSet { this.blockName = "Ixalan"; this.parentSet = Ixalan.getInstance(); this.hasBoosters = true; - this.hasBasicLands = false; + this.hasBasicLands = true; this.numBoosterLands = 0; this.numBoosterCommon = 11; this.numBoosterUncommon = 3; diff --git a/Mage.Sets/src/mage/sets/SuperSeries.java b/Mage.Sets/src/mage/sets/SuperSeries.java index 5d4ce44b78..c50c19245e 100644 --- a/Mage.Sets/src/mage/sets/SuperSeries.java +++ b/Mage.Sets/src/mage/sets/SuperSeries.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class SuperSeries extends ExpansionSet { @@ -20,6 +19,8 @@ public final class SuperSeries extends ExpansionSet { private SuperSeries() { super("Super Series", "SUS", ExpansionSet.buildDate(1996, 1, 1), SetType.PROMOTIONAL); this.hasBoosters = false; + this.hasBasicLands = false; + cards.add(new SetCardInfo("City of Brass", 6, Rarity.SPECIAL, mage.cards.c.CityOfBrass.class)); cards.add(new SetCardInfo("Crusade", 4, Rarity.SPECIAL, mage.cards.c.Crusade.class)); cards.add(new SetCardInfo("Elvish Champion", 17, Rarity.SPECIAL, mage.cards.e.ElvishChampion.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/UginsFate.java b/Mage.Sets/src/mage/sets/UginsFate.java index 07e234b6d5..a87356e6ea 100644 --- a/Mage.Sets/src/mage/sets/UginsFate.java +++ b/Mage.Sets/src/mage/sets/UginsFate.java @@ -6,7 +6,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class UginsFate extends ExpansionSet { @@ -20,6 +19,8 @@ public final class UginsFate extends ExpansionSet { private UginsFate() { super("Ugin's Fate", "UGIN", ExpansionSet.buildDate(2015, 1, 16), SetType.PROMOTIONAL); this.hasBoosters = false; + this.hasBasicLands = false; + cards.add(new SetCardInfo("Ainok Tracker", 96, Rarity.COMMON, mage.cards.a.AinokTracker.class)); cards.add(new SetCardInfo("Altar of the Brood", 216, Rarity.RARE, mage.cards.a.AltarOfTheBrood.class)); cards.add(new SetCardInfo("Arashin War Beast", 123, Rarity.UNCOMMON, mage.cards.a.ArashinWarBeast.class)); diff --git a/Mage/src/main/java/mage/cards/ExpansionSet.java b/Mage/src/main/java/mage/cards/ExpansionSet.java index df4b5ae8bd..488b32b044 100644 --- a/Mage/src/main/java/mage/cards/ExpansionSet.java +++ b/Mage/src/main/java/mage/cards/ExpansionSet.java @@ -88,6 +88,8 @@ public abstract class ExpansionSet implements Serializable { protected Date releaseDate; protected ExpansionSet parentSet; protected SetType setType; + + // TODO: 03.10.2018, hasBasicLands can be removed someday -- it's uses to optimize lands search in deck generation and lands adding (search all available lands from sets) protected boolean hasBasicLands = true; protected String blockName; @@ -559,6 +561,7 @@ public abstract class ExpansionSet implements Serializable { if (savedCardsInfos == null) { CardCriteria criteria = new CardCriteria(); if (rarity == Rarity.LAND) { + // get basic lands from parent set if current haven't it criteria.setCodes(!hasBasicLands && parentSet != null ? parentSet.code : this.code); } else { criteria.setCodes(this.code); From cbf6b9d5b593ace91ccfd31b919a3a4437f0466e Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 01:49:22 +0400 Subject: [PATCH 009/167] * Masters Edition II (ME2) - added 6 missing cards (Dry Spell, Mishra's Groundbreaker, Royal Decree, Varchild's Crusader, Whirling Catapult, Winter's Night) --- Mage.Sets/src/mage/sets/MastersEditionII.java | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index 4ffc5c6e5a..7002dff323 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -2,18 +2,6 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.a.ArmorThrull; -import mage.cards.b.BrassclawOrcs; -import mage.cards.c.CombatMedic; -import mage.cards.e.ElvishHunter; -import mage.cards.f.FarrelsZealot; -import mage.cards.g.GorillaShaman; -import mage.cards.i.IcatianJavelineers; -import mage.cards.i.IcatianScout; -import mage.cards.l.LimDulsHighGuard; -import mage.cards.n.Necrite; -import mage.cards.n.NightSoil; -import mage.cards.o.OrcishVeteran; import mage.constants.Rarity; import mage.constants.SetType; @@ -38,18 +26,18 @@ public final class MastersEditionII extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Aether Storm", 39, Rarity.UNCOMMON, mage.cards.a.AetherStorm.class)); cards.add(new SetCardInfo("Abbey Gargoyles", 1, Rarity.UNCOMMON, mage.cards.a.AbbeyGargoyles.class)); cards.add(new SetCardInfo("Adarkar Sentinel", 201, Rarity.COMMON, mage.cards.a.AdarkarSentinel.class)); cards.add(new SetCardInfo("Aeolipile", 202, Rarity.COMMON, mage.cards.a.Aeolipile.class)); + cards.add(new SetCardInfo("Aether Storm", 39, Rarity.UNCOMMON, mage.cards.a.AetherStorm.class)); cards.add(new SetCardInfo("Ambush Party", 115, Rarity.COMMON, mage.cards.a.AmbushParty.class)); cards.add(new SetCardInfo("An-Zerrin Ruins", 117, Rarity.RARE, mage.cards.a.AnZerrinRuins.class)); cards.add(new SetCardInfo("Anarchy", 116, Rarity.RARE, mage.cards.a.Anarchy.class)); cards.add(new SetCardInfo("Angel of Fury", 2, Rarity.RARE, mage.cards.a.AngelOfFury.class)); cards.add(new SetCardInfo("Angel of Light", 3, Rarity.UNCOMMON, mage.cards.a.AngelOfLight.class)); - cards.add(new SetCardInfo("Armored Griffin", 5, Rarity.COMMON, mage.cards.a.ArmoredGriffin.class)); cards.add(new SetCardInfo("Armor of Faith", 4, Rarity.COMMON, mage.cards.a.ArmorOfFaith.class)); - cards.add(new SetCardInfo("Armor Thrull", 77, Rarity.COMMON, ArmorThrull.class)); + cards.add(new SetCardInfo("Armor Thrull", 77, Rarity.COMMON, mage.cards.a.ArmorThrull.class)); + cards.add(new SetCardInfo("Armored Griffin", 5, Rarity.COMMON, mage.cards.a.ArmoredGriffin.class)); cards.add(new SetCardInfo("Ashen Ghoul", 78, Rarity.UNCOMMON, mage.cards.a.AshenGhoul.class)); cards.add(new SetCardInfo("Ashnod's Cylix", 203, Rarity.RARE, mage.cards.a.AshnodsCylix.class)); cards.add(new SetCardInfo("Aurochs", 153, Rarity.COMMON, mage.cards.a.Aurochs.class)); @@ -64,7 +52,7 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Binding Grasp", 41, Rarity.RARE, mage.cards.b.BindingGrasp.class)); cards.add(new SetCardInfo("Bounty of the Hunt", 154, Rarity.RARE, mage.cards.b.BountyOfTheHunt.class)); cards.add(new SetCardInfo("Brainstorm", 42, Rarity.COMMON, mage.cards.b.Brainstorm.class)); - cards.add(new SetCardInfo("Brassclaw Orcs", 119, Rarity.COMMON, BrassclawOrcs.class)); + cards.add(new SetCardInfo("Brassclaw Orcs", 119, Rarity.COMMON, mage.cards.b.BrassclawOrcs.class)); cards.add(new SetCardInfo("Brimstone Dragon", 120, Rarity.RARE, mage.cards.b.BrimstoneDragon.class)); cards.add(new SetCardInfo("Brine Shaman", 80, Rarity.COMMON, mage.cards.b.BrineShaman.class)); cards.add(new SetCardInfo("Broken Visage", 81, Rarity.UNCOMMON, mage.cards.b.BrokenVisage.class)); @@ -73,7 +61,7 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Carapace", 155, Rarity.COMMON, mage.cards.c.Carapace.class)); cards.add(new SetCardInfo("Caribou Range", 8, Rarity.RARE, mage.cards.c.CaribouRange.class)); cards.add(new SetCardInfo("Clockwork Steed", 205, Rarity.UNCOMMON, mage.cards.c.ClockworkSteed.class)); - cards.add(new SetCardInfo("Combat Medic", 9, Rarity.COMMON, CombatMedic.class)); + cards.add(new SetCardInfo("Combat Medic", 9, Rarity.COMMON, mage.cards.c.CombatMedic.class)); cards.add(new SetCardInfo("Conquer", 122, Rarity.UNCOMMON, mage.cards.c.Conquer.class)); cards.add(new SetCardInfo("Counterspell", 44, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); cards.add(new SetCardInfo("Dance of the Dead", 83, Rarity.UNCOMMON, mage.cards.d.DanceOfTheDead.class)); @@ -86,6 +74,7 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Disenchant", 10, Rarity.COMMON, mage.cards.d.Disenchant.class)); cards.add(new SetCardInfo("Dreams of the Dead", 46, Rarity.RARE, mage.cards.d.DreamsOfTheDead.class)); cards.add(new SetCardInfo("Drift of the Dead", 86, Rarity.COMMON, mage.cards.d.DriftOfTheDead.class)); + cards.add(new SetCardInfo("Dry Spell", 87, Rarity.COMMON, mage.cards.d.DrySpell.class)); cards.add(new SetCardInfo("Dwarven Ruins", 227, Rarity.UNCOMMON, mage.cards.d.DwarvenRuins.class)); cards.add(new SetCardInfo("Dystopia", 88, Rarity.RARE, mage.cards.d.Dystopia.class)); cards.add(new SetCardInfo("Earthlink", 192, Rarity.RARE, mage.cards.e.Earthlink.class)); @@ -95,7 +84,7 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Elkin Bottle", 207, Rarity.RARE, mage.cards.e.ElkinBottle.class)); cards.add(new SetCardInfo("Elven Lyre", 208, Rarity.COMMON, mage.cards.e.ElvenLyre.class)); cards.add(new SetCardInfo("Elvish Farmer", 156, Rarity.RARE, mage.cards.e.ElvishFarmer.class)); - cards.add(new SetCardInfo("Elvish Hunter", 157, Rarity.COMMON, ElvishHunter.class)); + cards.add(new SetCardInfo("Elvish Hunter", 157, Rarity.COMMON, mage.cards.e.ElvishHunter.class)); cards.add(new SetCardInfo("Elvish Ranger", 158, Rarity.COMMON, mage.cards.e.ElvishRanger.class)); cards.add(new SetCardInfo("Elvish Spirit Guide", 159, Rarity.UNCOMMON, mage.cards.e.ElvishSpiritGuide.class)); cards.add(new SetCardInfo("Energy Storm", 11, Rarity.RARE, mage.cards.e.EnergyStorm.class)); @@ -105,7 +94,7 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Essence Filter", 160, Rarity.UNCOMMON, mage.cards.e.EssenceFilter.class)); cards.add(new SetCardInfo("Essence Flare", 48, Rarity.COMMON, mage.cards.e.EssenceFlare.class)); cards.add(new SetCardInfo("Farrel's Mantle", 13, Rarity.UNCOMMON, mage.cards.f.FarrelsMantle.class)); - cards.add(new SetCardInfo("Farrel's Zealot", 14, Rarity.UNCOMMON, FarrelsZealot.class)); + cards.add(new SetCardInfo("Farrel's Zealot", 14, Rarity.UNCOMMON, mage.cards.f.FarrelsZealot.class)); cards.add(new SetCardInfo("Feral Thallid", 161, Rarity.COMMON, mage.cards.f.FeralThallid.class)); cards.add(new SetCardInfo("Fire Dragon", 125, Rarity.RARE, mage.cards.f.FireDragon.class)); cards.add(new SetCardInfo("Flame Spirit", 126, Rarity.UNCOMMON, mage.cards.f.FlameSpirit.class)); @@ -122,14 +111,14 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Giant Trap Door Spider", 195, Rarity.UNCOMMON, mage.cards.g.GiantTrapDoorSpider.class)); cards.add(new SetCardInfo("Glacial Chasm", 229, Rarity.RARE, mage.cards.g.GlacialChasm.class)); cards.add(new SetCardInfo("Glacial Crevasses", 127, Rarity.RARE, mage.cards.g.GlacialCrevasses.class)); - cards.add(new SetCardInfo("Gorilla Shaman", 129, Rarity.UNCOMMON, GorillaShaman.class)); + cards.add(new SetCardInfo("Gorilla Shaman", 129, Rarity.UNCOMMON, mage.cards.g.GorillaShaman.class)); cards.add(new SetCardInfo("Grandmother Sengir", 93, Rarity.RARE, mage.cards.g.GrandmotherSengir.class)); cards.add(new SetCardInfo("Havenwood Battleground", 230, Rarity.UNCOMMON, mage.cards.h.HavenwoodBattleground.class)); cards.add(new SetCardInfo("Heart of Yavimaya", 231, Rarity.RARE, mage.cards.h.HeartOfYavimaya.class)); cards.add(new SetCardInfo("Helm of Obedience", 210, Rarity.RARE, mage.cards.h.HelmOfObedience.class)); - cards.add(new SetCardInfo("Icatian Javelineers", 15, Rarity.COMMON, IcatianJavelineers.class)); + cards.add(new SetCardInfo("Icatian Javelineers", 15, Rarity.COMMON, mage.cards.i.IcatianJavelineers.class)); cards.add(new SetCardInfo("Icatian Phalanx", 16, Rarity.COMMON, mage.cards.i.IcatianPhalanx.class)); - cards.add(new SetCardInfo("Icatian Scout", 17, Rarity.COMMON, IcatianScout.class)); + cards.add(new SetCardInfo("Icatian Scout", 17, Rarity.COMMON, mage.cards.i.IcatianScout.class)); cards.add(new SetCardInfo("Ice Floe", 232, Rarity.UNCOMMON, mage.cards.i.IceFloe.class)); cards.add(new SetCardInfo("Iceberg", 49, Rarity.UNCOMMON, mage.cards.i.Iceberg.class)); cards.add(new SetCardInfo("Icequake", 94, Rarity.COMMON, mage.cards.i.Icequake.class)); @@ -159,7 +148,7 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Krovikan Sorcerer", 51, Rarity.COMMON, mage.cards.k.KrovikanSorcerer.class)); cards.add(new SetCardInfo("Lat-Nam's Legacy", 52, Rarity.COMMON, mage.cards.l.LatNamsLegacy.class)); cards.add(new SetCardInfo("Leaping Lizard", 171, Rarity.COMMON, mage.cards.l.LeapingLizard.class)); - cards.add(new SetCardInfo("Lim-Dul's High Guard", 103, Rarity.UNCOMMON, LimDulsHighGuard.class)); + cards.add(new SetCardInfo("Lim-Dul's High Guard", 103, Rarity.UNCOMMON, mage.cards.l.LimDulsHighGuard.class)); cards.add(new SetCardInfo("Lodestone Bauble", 213, Rarity.RARE, mage.cards.l.LodestoneBauble.class)); cards.add(new SetCardInfo("Magus of the Unseen", 53, Rarity.RARE, mage.cards.m.MagusOfTheUnseen.class)); cards.add(new SetCardInfo("Mana Crypt", 214, Rarity.RARE, mage.cards.m.ManaCrypt.class)); @@ -167,20 +156,21 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Mesmeric Trance", 55, Rarity.RARE, mage.cards.m.MesmericTrance.class)); cards.add(new SetCardInfo("Meteor Shower", 135, Rarity.COMMON, mage.cards.m.MeteorShower.class)); cards.add(new SetCardInfo("Minion of Leshrac", 104, Rarity.RARE, mage.cards.m.MinionOfLeshrac.class)); + cards.add(new SetCardInfo("Mishra's Groundbreaker", 215, Rarity.UNCOMMON, mage.cards.m.MishrasGroundbreaker.class)); cards.add(new SetCardInfo("Misinformation", 105, Rarity.UNCOMMON, mage.cards.m.Misinformation.class)); cards.add(new SetCardInfo("Mudslide", 136, Rarity.RARE, mage.cards.m.Mudslide.class)); cards.add(new SetCardInfo("Narwhal", 57, Rarity.UNCOMMON, mage.cards.n.Narwhal.class)); cards.add(new SetCardInfo("Nature's Blessing", 196, Rarity.UNCOMMON, mage.cards.n.NaturesBlessing.class)); cards.add(new SetCardInfo("Nature's Wrath", 172, Rarity.RARE, mage.cards.n.NaturesWrath.class)); - cards.add(new SetCardInfo("Necrite", 106, Rarity.COMMON, Necrite.class)); + cards.add(new SetCardInfo("Necrite", 106, Rarity.COMMON, mage.cards.n.Necrite.class)); cards.add(new SetCardInfo("Necropotence", 107, Rarity.RARE, mage.cards.n.Necropotence.class)); - cards.add(new SetCardInfo("Night Soil", 173, Rarity.UNCOMMON, NightSoil.class)); + cards.add(new SetCardInfo("Night Soil", 173, Rarity.UNCOMMON, mage.cards.n.NightSoil.class)); cards.add(new SetCardInfo("Orc General", 137, Rarity.UNCOMMON, mage.cards.o.OrcGeneral.class)); cards.add(new SetCardInfo("Orcish Cannoneers", 138, Rarity.UNCOMMON, mage.cards.o.OrcishCannoneers.class)); cards.add(new SetCardInfo("Orcish Captain", 139, Rarity.UNCOMMON, mage.cards.o.OrcishCaptain.class)); cards.add(new SetCardInfo("Orcish Lumberjack", 142, Rarity.COMMON, mage.cards.o.OrcishLumberjack.class)); cards.add(new SetCardInfo("Orcish Squatters", 143, Rarity.RARE, mage.cards.o.OrcishSquatters.class)); - cards.add(new SetCardInfo("Orcish Veteran", 144, Rarity.COMMON, OrcishVeteran.class)); + cards.add(new SetCardInfo("Orcish Veteran", 144, Rarity.COMMON, mage.cards.o.OrcishVeteran.class)); cards.add(new SetCardInfo("Order of the Sacred Torch", 25, Rarity.RARE, mage.cards.o.OrderOfTheSacredTorch.class)); cards.add(new SetCardInfo("Order of the White Shield", 26, Rarity.UNCOMMON, mage.cards.o.OrderOfTheWhiteShield.class)); cards.add(new SetCardInfo("Panic", 145, Rarity.COMMON, mage.cards.p.Panic.class)); @@ -200,6 +190,7 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Ritual of Subdual", 174, Rarity.RARE, mage.cards.r.RitualOfSubdual.class)); cards.add(new SetCardInfo("Ritual of the Machine", 109, Rarity.RARE, mage.cards.r.RitualOfTheMachine.class)); cards.add(new SetCardInfo("Roterothopter", 218, Rarity.COMMON, mage.cards.r.Roterothopter.class)); + cards.add(new SetCardInfo("Royal Decree", 31, Rarity.RARE, mage.cards.r.RoyalDecree.class)); cards.add(new SetCardInfo("Royal Trooper", 32, Rarity.COMMON, mage.cards.r.RoyalTrooper.class)); cards.add(new SetCardInfo("Ruins of Trokair", 234, Rarity.UNCOMMON, mage.cards.r.RuinsOfTrokair.class)); cards.add(new SetCardInfo("Savannah", 235, Rarity.RARE, mage.cards.s.Savannah.class)); @@ -227,8 +218,8 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Spore Cloud", 176, Rarity.UNCOMMON, mage.cards.s.SporeCloud.class)); cards.add(new SetCardInfo("Spore Flower", 177, Rarity.UNCOMMON, mage.cards.s.SporeFlower.class)); cards.add(new SetCardInfo("Stampede", 178, Rarity.UNCOMMON, mage.cards.s.Stampede.class)); - cards.add(new SetCardInfo("Stonehands", 151, Rarity.COMMON, mage.cards.s.Stonehands.class)); cards.add(new SetCardInfo("Stone Spirit", 150, Rarity.UNCOMMON, mage.cards.s.StoneSpirit.class)); + cards.add(new SetCardInfo("Stonehands", 151, Rarity.COMMON, mage.cards.s.Stonehands.class)); cards.add(new SetCardInfo("Storm Spirit", 198, Rarity.RARE, mage.cards.s.StormSpirit.class)); cards.add(new SetCardInfo("Stromgald Cabal", 113, Rarity.RARE, mage.cards.s.StromgaldCabal.class)); cards.add(new SetCardInfo("Stunted Growth", 179, Rarity.RARE, mage.cards.s.StuntedGrowth.class)); @@ -237,8 +228,8 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Swords to Plowshares", 37, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); cards.add(new SetCardInfo("Taiga", 238, Rarity.RARE, mage.cards.t.Taiga.class)); cards.add(new SetCardInfo("Temporal Manipulation", 69, Rarity.RARE, mage.cards.t.TemporalManipulation.class)); - cards.add(new SetCardInfo("Thallid", 180, Rarity.COMMON, mage.cards.t.Thallid.class)); cards.add(new SetCardInfo("Thallid Devourer", 181, Rarity.COMMON, mage.cards.t.ThallidDevourer.class)); + cards.add(new SetCardInfo("Thallid", 180, Rarity.COMMON, mage.cards.t.Thallid.class)); cards.add(new SetCardInfo("Thelonite Druid", 182, Rarity.RARE, mage.cards.t.TheloniteDruid.class)); cards.add(new SetCardInfo("Thermokarst", 183, Rarity.COMMON, mage.cards.t.Thermokarst.class)); cards.add(new SetCardInfo("Thought Lash", 70, Rarity.RARE, mage.cards.t.ThoughtLash.class)); @@ -247,13 +238,16 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Tinder Wall", 184, Rarity.COMMON, mage.cards.t.TinderWall.class)); cards.add(new SetCardInfo("Tundra", 239, Rarity.RARE, mage.cards.t.Tundra.class)); cards.add(new SetCardInfo("Underground Sea", 240, Rarity.RARE, mage.cards.u.UndergroundSea.class)); + cards.add(new SetCardInfo("Varchild's Crusader", 152, Rarity.COMMON, mage.cards.v.VarchildsCrusader.class)); cards.add(new SetCardInfo("Viscerid Armor", 72, Rarity.COMMON, mage.cards.v.VisceridArmor.class)); cards.add(new SetCardInfo("Viscerid Drone", 73, Rarity.UNCOMMON, mage.cards.v.VisceridDrone.class)); cards.add(new SetCardInfo("Wall of Kelp", 74, Rarity.COMMON, mage.cards.w.WallOfKelp.class)); cards.add(new SetCardInfo("Warning", 38, Rarity.COMMON, mage.cards.w.Warning.class)); + cards.add(new SetCardInfo("Whirling Catapult", 224, Rarity.UNCOMMON, mage.cards.w.WhirlingCatapult.class)); cards.add(new SetCardInfo("Whiteout", 185, Rarity.COMMON, mage.cards.w.Whiteout.class)); cards.add(new SetCardInfo("Wind Spirit", 75, Rarity.UNCOMMON, mage.cards.w.WindSpirit.class)); cards.add(new SetCardInfo("Wings of Aesthir", 199, Rarity.UNCOMMON, mage.cards.w.WingsOfAesthir.class)); + cards.add(new SetCardInfo("Winter's Night", 200, Rarity.RARE, mage.cards.w.WintersNight.class)); cards.add(new SetCardInfo("Withering Wisps", 114, Rarity.UNCOMMON, mage.cards.w.WitheringWisps.class)); cards.add(new SetCardInfo("Wolf Pack", 187, Rarity.RARE, mage.cards.w.WolfPack.class)); cards.add(new SetCardInfo("Woolly Mammoths", 188, Rarity.COMMON, mage.cards.w.WoollyMammoths.class)); @@ -261,5 +255,4 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Yavimaya Ancients", 190, Rarity.UNCOMMON, mage.cards.y.YavimayaAncients.class)); cards.add(new SetCardInfo("Zuran Spellcaster", 76, Rarity.COMMON, mage.cards.z.ZuranSpellcaster.class)); } - } From fccae9b8cd4f2aaa45be63004c944e332f7dff40 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 01:52:16 +0400 Subject: [PATCH 010/167] * Added new set Anthologies (ATH) with 85 cards; --- .../card/dl/sources/ScryfallImageSource.java | 1 + Mage.Sets/src/mage/sets/Anthologies.java | 110 ++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/Anthologies.java diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 29b907198c..294d660503 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -237,6 +237,7 @@ public enum ScryfallImageSource implements CardImageSource { // supportedSets.add("EURO"); supportedSets.add("GPX"); + supportedSets.add("ATH"); } @Override diff --git a/Mage.Sets/src/mage/sets/Anthologies.java b/Mage.Sets/src/mage/sets/Anthologies.java new file mode 100644 index 0000000000..02d7f59605 --- /dev/null +++ b/Mage.Sets/src/mage/sets/Anthologies.java @@ -0,0 +1,110 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author JayDi85 + */ +public final class Anthologies extends ExpansionSet { + + private static final Anthologies instance = new Anthologies(); + + public static Anthologies getInstance() { + return instance; + } + + private Anthologies() { + super("Anthologies", "ATH", ExpansionSet.buildDate(1998, 11, 01), SetType.SUPPLEMENTAL); + this.hasBoosters = false; + this.hasBasicLands = false; + + cards.add(new SetCardInfo("Aesthir Glider", 67, Rarity.COMMON, mage.cards.a.AesthirGlider.class)); + cards.add(new SetCardInfo("Armageddon", 1, Rarity.RARE, mage.cards.a.Armageddon.class)); + cards.add(new SetCardInfo("Armored Pegasus", 2, Rarity.COMMON, mage.cards.a.ArmoredPegasus.class)); + cards.add(new SetCardInfo("Benalish Knight", 3, Rarity.COMMON, mage.cards.b.BenalishKnight.class)); + cards.add(new SetCardInfo("Black Knight", 20, Rarity.UNCOMMON, mage.cards.b.BlackKnight.class)); + cards.add(new SetCardInfo("Brushland", 71, Rarity.RARE, mage.cards.b.Brushland.class)); + cards.add(new SetCardInfo("Canopy Spider", 52, Rarity.COMMON, mage.cards.c.CanopySpider.class)); + cards.add(new SetCardInfo("Carnivorous Plant", 53, Rarity.COMMON, mage.cards.c.CarnivorousPlant.class)); + cards.add(new SetCardInfo("Combat Medic", 4, Rarity.COMMON, mage.cards.c.CombatMedic.class)); + cards.add(new SetCardInfo("Cuombajj Witches", 21, Rarity.COMMON, mage.cards.c.CuombajjWitches.class)); + cards.add(new SetCardInfo("Disenchant", 5, Rarity.COMMON, mage.cards.d.Disenchant.class)); + cards.add(new SetCardInfo("Drifting Meadow", 72, Rarity.COMMON, mage.cards.d.DriftingMeadow.class)); + cards.add(new SetCardInfo("Erhnam Djinn", 54, Rarity.UNCOMMON, mage.cards.e.ErhnamDjinn.class)); + cards.add(new SetCardInfo("Feast of the Unicorn", 22, Rarity.COMMON, mage.cards.f.FeastOfTheUnicorn.class)); + cards.add(new SetCardInfo("Fireball", 29, Rarity.COMMON, mage.cards.f.Fireball.class)); + cards.add(new SetCardInfo("Forest", 84, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 85, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Freewind Falcon", 6, Rarity.COMMON, mage.cards.f.FreewindFalcon.class)); + cards.add(new SetCardInfo("Giant Growth", 55, Rarity.COMMON, mage.cards.g.GiantGrowth.class)); + cards.add(new SetCardInfo("Giant Spider", 56, Rarity.COMMON, mage.cards.g.GiantSpider.class)); + cards.add(new SetCardInfo("Goblin Balloon Brigade", 30, Rarity.COMMON, mage.cards.g.GoblinBalloonBrigade.class)); + cards.add(new SetCardInfo("Goblin Digging Team", 31, Rarity.COMMON, mage.cards.g.GoblinDiggingTeam.class)); + cards.add(new SetCardInfo("Goblin Grenade", 32, Rarity.COMMON, mage.cards.g.GoblinGrenade.class)); + cards.add(new SetCardInfo("Goblin Hero", 33, Rarity.COMMON, mage.cards.g.GoblinHero.class)); + cards.add(new SetCardInfo("Goblin King", 34, Rarity.RARE, mage.cards.g.GoblinKing.class)); + cards.add(new SetCardInfo("Goblin Matron", 35, Rarity.UNCOMMON, mage.cards.g.GoblinMatron.class)); + cards.add(new SetCardInfo("Goblin Mutant", 36, Rarity.UNCOMMON, mage.cards.g.GoblinMutant.class)); + cards.add(new SetCardInfo("Goblin Offensive", 37, Rarity.UNCOMMON, mage.cards.g.GoblinOffensive.class)); + cards.add(new SetCardInfo("Goblin Recruiter", 38, Rarity.UNCOMMON, mage.cards.g.GoblinRecruiter.class)); + cards.add(new SetCardInfo("Goblin Snowman", 39, Rarity.UNCOMMON, mage.cards.g.GoblinSnowman.class)); + cards.add(new SetCardInfo("Goblin Tinkerer", 40, Rarity.COMMON, mage.cards.g.GoblinTinkerer.class)); + cards.add(new SetCardInfo("Goblin Vandal", 41, Rarity.COMMON, mage.cards.g.GoblinVandal.class)); + cards.add(new SetCardInfo("Goblin Warrens", 42, Rarity.RARE, mage.cards.g.GoblinWarrens.class)); + cards.add(new SetCardInfo("Gorilla Chieftain", 57, Rarity.COMMON, mage.cards.g.GorillaChieftain.class)); + cards.add(new SetCardInfo("Hurricane", 58, Rarity.UNCOMMON, mage.cards.h.Hurricane.class)); + cards.add(new SetCardInfo("Hymn to Tourach", 23, Rarity.COMMON, mage.cards.h.HymnToTourach.class)); + cards.add(new SetCardInfo("Hypnotic Specter", 24, Rarity.UNCOMMON, mage.cards.h.HypnoticSpecter.class)); + cards.add(new SetCardInfo("Icatian Javelineers", 7, Rarity.COMMON, mage.cards.i.IcatianJavelineers.class)); + cards.add(new SetCardInfo("Ihsan's Shade", 25, Rarity.UNCOMMON, mage.cards.i.IhsansShade.class)); + cards.add(new SetCardInfo("Infantry Veteran", 8, Rarity.COMMON, mage.cards.i.InfantryVeteran.class)); + cards.add(new SetCardInfo("Jalum Tome", 68, Rarity.UNCOMMON, mage.cards.j.JalumTome.class)); + cards.add(new SetCardInfo("Knight of Stromgald", 26, Rarity.UNCOMMON, mage.cards.k.KnightOfStromgald.class)); + cards.add(new SetCardInfo("Lady Orca", 65, Rarity.UNCOMMON, mage.cards.l.LadyOrca.class)); + cards.add(new SetCardInfo("Lightning Bolt", 43, Rarity.COMMON, mage.cards.l.LightningBolt.class)); + cards.add(new SetCardInfo("Llanowar Elves", 59, Rarity.COMMON, mage.cards.l.LlanowarElves.class)); + cards.add(new SetCardInfo("Mirri, Cat Warrior", 60, Rarity.UNCOMMON, mage.cards.m.MirriCatWarrior.class)); + cards.add(new SetCardInfo("Mogg Fanatic", 44, Rarity.COMMON, mage.cards.m.MoggFanatic.class)); + cards.add(new SetCardInfo("Mogg Flunkies", 45, Rarity.COMMON, mage.cards.m.MoggFlunkies.class)); + cards.add(new SetCardInfo("Mogg Raider", 46, Rarity.COMMON, mage.cards.m.MoggRaider.class)); + cards.add(new SetCardInfo("Mountain", 82, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 83, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Nevinyrral's Disk", 69, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); + cards.add(new SetCardInfo("Order of the White Shield", 9, Rarity.UNCOMMON, mage.cards.o.OrderOfTheWhiteShield.class)); + cards.add(new SetCardInfo("Overrun", 61, Rarity.UNCOMMON, mage.cards.o.Overrun.class)); + cards.add(new SetCardInfo("Pacifism", 10, Rarity.COMMON, mage.cards.p.Pacifism.class)); + cards.add(new SetCardInfo("Pegasus Charger", 11, Rarity.COMMON, mage.cards.p.PegasusCharger.class)); + cards.add(new SetCardInfo("Pegasus Stampede", 12, Rarity.UNCOMMON, mage.cards.p.PegasusStampede.class)); + cards.add(new SetCardInfo("Pendelhaven", 73, Rarity.UNCOMMON, mage.cards.p.Pendelhaven.class)); + cards.add(new SetCardInfo("Plains", 78, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 79, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Polluted Mire", 74, Rarity.COMMON, mage.cards.p.PollutedMire.class)); + cards.add(new SetCardInfo("Pyrokinesis", 47, Rarity.UNCOMMON, mage.cards.p.Pyrokinesis.class)); + cards.add(new SetCardInfo("Pyrotechnics", 48, Rarity.COMMON, mage.cards.p.Pyrotechnics.class)); + cards.add(new SetCardInfo("Raging Goblin", 49, Rarity.UNCOMMON, mage.cards.r.RagingGoblin.class)); + cards.add(new SetCardInfo("Ranger en-Vec", 66, Rarity.UNCOMMON, mage.cards.r.RangerEnVec.class)); + cards.add(new SetCardInfo("Sacred Mesa", 13, Rarity.RARE, mage.cards.s.SacredMesa.class)); + cards.add(new SetCardInfo("Samite Healer", 14, Rarity.COMMON, mage.cards.s.SamiteHealer.class)); + cards.add(new SetCardInfo("Scavenger Folk", 62, Rarity.COMMON, mage.cards.s.ScavengerFolk.class)); + cards.add(new SetCardInfo("Serra Angel", 15, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class)); + cards.add(new SetCardInfo("Serrated Arrows", 70, Rarity.COMMON, mage.cards.s.SerratedArrows.class)); + cards.add(new SetCardInfo("Slippery Karst", 75, Rarity.COMMON, mage.cards.s.SlipperyKarst.class)); + cards.add(new SetCardInfo("Smoldering Crater", 76, Rarity.COMMON, mage.cards.s.SmolderingCrater.class)); + cards.add(new SetCardInfo("Spectral Bears", 63, Rarity.UNCOMMON, mage.cards.s.SpectralBears.class)); + cards.add(new SetCardInfo("Strip Mine", 77, Rarity.RARE, mage.cards.s.StripMine.class)); + cards.add(new SetCardInfo("Swamp", 80, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 81, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swords to Plowshares", 16, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); + cards.add(new SetCardInfo("Terror", 27, Rarity.COMMON, mage.cards.t.Terror.class)); + cards.add(new SetCardInfo("Unholy Strength", 28, Rarity.COMMON, mage.cards.u.UnholyStrength.class)); + cards.add(new SetCardInfo("Uthden Troll", 50, Rarity.UNCOMMON, mage.cards.u.UthdenTroll.class)); + cards.add(new SetCardInfo("Volcanic Dragon", 51, Rarity.RARE, mage.cards.v.VolcanicDragon.class)); + cards.add(new SetCardInfo("Warrior's Honor", 17, Rarity.COMMON, mage.cards.w.WarriorsHonor.class)); + cards.add(new SetCardInfo("White Knight", 18, Rarity.UNCOMMON, mage.cards.w.WhiteKnight.class)); + cards.add(new SetCardInfo("Woolly Spider", 64, Rarity.COMMON, mage.cards.w.WoollySpider.class)); + cards.add(new SetCardInfo("Youthful Knight", 19, Rarity.COMMON, mage.cards.y.YouthfulKnight.class)); + } +} From 27fc2f5610cf42c43b64e8165cb293d7463344a5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 2 Oct 2018 21:50:29 -0400 Subject: [PATCH 011/167] fixed Elf Knight token name --- .../java/mage/game/permanent/token/ElfKnightToken.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mage/src/main/java/mage/game/permanent/token/ElfKnightToken.java b/Mage/src/main/java/mage/game/permanent/token/ElfKnightToken.java index ecb2764cda..b2483d23fb 100644 --- a/Mage/src/main/java/mage/game/permanent/token/ElfKnightToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/ElfKnightToken.java @@ -1,18 +1,17 @@ package mage.game.permanent.token; -import mage.constants.CardType; -import mage.constants.SubType; import mage.MageInt; import mage.abilities.keyword.VigilanceAbility; +import mage.constants.CardType; +import mage.constants.SubType; /** - * * @author TheElk801 */ public final class ElfKnightToken extends TokenImpl { public ElfKnightToken() { - super("Knight Ally", "2/2 green and white Elf Knight creature token with vigilance"); + super("Elf Knight", "2/2 green and white Elf Knight creature token with vigilance"); this.setExpansionSetCodeForImage("GRN"); cardType.add(CardType.CREATURE); color.setGreen(true); From b2f050df358e3f75ca1cac56a55674d136b138b6 Mon Sep 17 00:00:00 2001 From: Richard Coates Date: Wed, 3 Oct 2018 09:17:16 +0200 Subject: [PATCH 012/167] Update EtrataTheSilencer.java Make the filter for cardsFound trigger on "greater than or equal to" rather than just "greater than". --- Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java b/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java index 8d28bb9cca..9ced408831 100644 --- a/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java +++ b/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java @@ -145,7 +145,7 @@ class EtrataTheSilencerEffect extends OneShotEffect { } int cardsFound = 0; for (Card exiledCard : game.getExile().getAllCards(game)) { - if (exiledCard.getCounters(game).getCount(CounterType.HIT) > 1 && exiledCard.getOwnerId().equals(player.getId())) { + if (exiledCard.getCounters(game).getCount(CounterType.HIT) >= 1 && exiledCard.getOwnerId().equals(player.getId())) { cardsFound++; } } From ac8540216fb1e9a749de87af47b883f60eb86121 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 13:26:37 +0400 Subject: [PATCH 013/167] Refactor: source cleanup at imports --- .../src/mage/cards/a/AberrantResearcher.java | 7 +- Mage.Sets/src/mage/cards/a/AccursedWitch.java | 5 +- .../src/mage/cards/a/AfflictedDeserter.java | 7 +- .../src/mage/cards/a/AnakinSkywalker.java | 5 +- .../src/mage/cards/a/ArguelsBloodFast.java | 5 +- .../mage/cards/a/AvacynianMissionaries.java | 7 +- Mage.Sets/src/mage/cards/a/AzorsGateway.java | 5 +- .../src/mage/cards/b/BloodlineKeeper.java | 5 +- .../src/mage/cards/b/BreakneckRider.java | 9 +- .../src/mage/cards/c/ChosenOfMarkov.java | 7 +- .../src/mage/cards/c/CivilizedScholar.java | 6 +- .../src/mage/cards/c/CloisteredYouth.java | 7 +- .../src/mage/cards/c/ConvictedKiller.java | 7 +- .../src/mage/cards/c/CryptolithFragment.java | 7 +- .../src/mage/cards/c/CuriousHomunculus.java | 5 +- Mage.Sets/src/mage/cards/d/DaringSleuth.java | 8 +- .../src/mage/cards/d/DaybreakRanger.java | 9 +- .../src/mage/cards/d/DelverOfSecrets.java | 23 +- .../src/mage/cards/d/DiligentFarmhand.java | 8 +- .../src/mage/cards/d/DocentOfPerfection.java | 10 +- Mage.Sets/src/mage/cards/d/DowsingDagger.java | 7 +- .../src/mage/cards/d/DuskwatchRecruiter.java | 6 +- .../mage/cards/e/ElbrusTheBindingBlade.java | 11 +- .../src/mage/cards/e/ElusiveTormentor.java | 7 +- .../src/mage/cards/g/GeierReachBandit.java | 9 +- .../mage/cards/g/GiselaTheBrokenBlade.java | 13 +- Mage.Sets/src/mage/cards/g/GrafRats.java | 9 +- .../src/mage/cards/g/GrizzledOutcasts.java | 8 +- .../mage/cards/g/GrowingRitesOfItlimoc.java | 6 +- Mage.Sets/src/mage/cards/h/HadanasClimb.java | 5 +- .../mage/cards/h/HanweirMilitiaCaptain.java | 7 +- .../src/mage/cards/h/HanweirWatchkeep.java | 6 +- Mage.Sets/src/mage/cards/h/HarvestHand.java | 7 +- .../mage/cards/h/HermitOfTheNatterknolls.java | 7 +- .../src/mage/cards/h/HinterlandLogger.java | 7 +- .../mage/cards/h/HuntmasterOfTheFells.java | 7 +- .../src/mage/cards/i/InstigatorGang.java | 12 +- ...dofKonda.java => IsamaruHoundOfKonda.java} | 14 +- .../src/mage/cards/j/JourneyToEternity.java | 5 +- .../src/mage/cards/k/KessigForgemaster.java | 5 +- Mage.Sets/src/mage/cards/k/KessigProwler.java | 7 +- .../src/mage/cards/k/KindlyStranger.java | 7 +- Mage.Sets/src/mage/cards/k/KruinOutlaw.java | 7 +- .../src/mage/cards/k/KytheonHeroOfAkros.java | 5 +- Mage.Sets/src/mage/cards/l/LambholtElder.java | 9 +- .../src/mage/cards/l/LegionsLanding.java | 7 +- Mage.Sets/src/mage/cards/l/LoneRider.java | 5 +- Mage.Sets/src/mage/cards/l/LoyalCathar.java | 8 +- .../src/mage/cards/m/MayorOfAvabruck.java | 7 +- .../src/mage/cards/m/MondronenShaman.java | 11 +- Mage.Sets/src/mage/cards/n/NecroticOoze.java | 7 +- .../src/mage/cards/n/NeglectedHeirloom.java | 7 +- Mage.Sets/src/mage/cards/p/PardicFirecat.java | 9 +- Mage.Sets/src/mage/cards/p/PathOfMettle.java | 8 +- Mage.Sets/src/mage/cards/p/PiousEvangel.java | 9 +- .../src/mage/cards/p/ProfaneProcession.java | 7 +- Mage.Sets/src/mage/cards/r/RavenousDemon.java | 9 +- Mage.Sets/src/mage/cards/r/RecklessWaif.java | 6 +- .../src/mage/cards/s/SageOfAncientLore.java | 13 +- .../src/mage/cards/s/ScornedVillager.java | 7 +- Mage.Sets/src/mage/cards/s/SealAway.java | 3 +- .../src/mage/cards/s/SearchForAzcanta.java | 7 +- Mage.Sets/src/mage/cards/s/ShrillHowler.java | 9 +- .../src/mage/cards/s/SmolderingWerewolf.java | 9 +- .../src/mage/cards/s/SolitaryHunter.java | 9 +- Mage.Sets/src/mage/cards/s/SoulSeizer.java | 11 +- Mage.Sets/src/mage/cards/s/StartledAwake.java | 9 +- Mage.Sets/src/mage/cards/s/StormTheVault.java | 7 +- .../src/mage/cards/t/TangleclawWerewolf.java | 7 +- .../src/mage/cards/t/ThaumaticCompass.java | 5 +- Mage.Sets/src/mage/cards/t/ThingInTheIce.java | 7 +- ...eggedKami.java => ThousandLeggedKami.java} | 13 +- .../src/mage/cards/t/ThrabenGargoyle.java | 7 +- .../src/mage/cards/t/TormentedPariah.java | 6 +- .../src/mage/cards/t/TownGossipmonger.java | 15 +- .../mage/cards/v/VancesBlastingCannons.java | 5 +- .../src/mage/cards/v/VildinPackOutcast.java | 7 +- .../src/mage/cards/v/VillageIronsmith.java | 6 +- .../src/mage/cards/v/VillageMessenger.java | 9 +- .../src/mage/cards/v/VillagersOfEstwald.java | 6 +- .../src/mage/cards/v/VoldarenPariah.java | 7 +- Mage.Sets/src/mage/cards/w/WestvaleAbbey.java | 5 +- .../src/mage/cards/w/WolfbittenCaptive.java | 7 +- Mage.Sets/src/mage/sets/Anthologies.java | 2 +- Mage.Sets/src/mage/sets/ArabianNights.java | 37 ++- .../src/mage/sets/ChampionsOfKamigawa.java | 27 +- .../src/mage/sets/ClassicSixthEdition.java | 19 +- .../src/mage/sets/Commander2013Edition.java | 7 +- .../mage/sets/DuelDecksElspethVsKiora.java | 3 +- Mage.Sets/src/mage/sets/EternalMasters.java | 8 +- Mage.Sets/src/mage/sets/FallenEmpires.java | 245 ++++++++---------- Mage.Sets/src/mage/sets/Homelands.java | 62 ++--- Mage.Sets/src/mage/sets/MastersEdition.java | 41 +-- .../src/mage/sets/MastersEditionIII.java | 8 +- Mage.Sets/src/mage/sets/MastersEditionIV.java | 9 +- Mage.Sets/src/mage/sets/MediaInserts.java | 6 +- Mage.Sets/src/mage/sets/Mirage.java | 7 +- Mage.Sets/src/mage/sets/NinthEdition.java | 10 +- Mage.Sets/src/mage/sets/NinthEditionBox.java | 1 + .../src/mage/sets/OathOfTheGatewatch.java | 12 +- Mage.Sets/src/mage/sets/Planeshift.java | 19 +- Mage.Sets/src/mage/sets/Portal.java | 18 +- Mage.Sets/src/mage/sets/SeventhEdition.java | 10 +- 103 files changed, 512 insertions(+), 680 deletions(-) rename Mage.Sets/src/mage/cards/i/{IsamaruHoundofKonda.java => IsamaruHoundOfKonda.java} (57%) rename Mage.Sets/src/mage/cards/t/{ThousandleggedKami.java => ThousandLeggedKami.java} (58%) diff --git a/Mage.Sets/src/mage/cards/a/AberrantResearcher.java b/Mage.Sets/src/mage/cards/a/AberrantResearcher.java index 5d78e0d59b..54c1bd42d4 100644 --- a/Mage.Sets/src/mage/cards/a/AberrantResearcher.java +++ b/Mage.Sets/src/mage/cards/a/AberrantResearcher.java @@ -2,6 +2,7 @@ package mage.cards.a; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,26 +13,24 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.p.PerfectedForm; import mage.constants.*; import mage.game.Game; import mage.players.Player; /** - * * @author fireshoes */ public final class AberrantResearcher extends CardImpl { public AberrantResearcher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.INSECT); this.power = new MageInt(3); this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = PerfectedForm.class; + this.secondSideCardClazz = mage.cards.p.PerfectedForm.class; // Flying this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/a/AccursedWitch.java b/Mage.Sets/src/mage/cards/a/AccursedWitch.java index e9848340da..1cefa7ff16 100644 --- a/Mage.Sets/src/mage/cards/a/AccursedWitch.java +++ b/Mage.Sets/src/mage/cards/a/AccursedWitch.java @@ -2,6 +2,7 @@ package mage.cards.a; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.Mode; @@ -14,7 +15,6 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.i.InfectiousCurse; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; @@ -23,7 +23,6 @@ import mage.target.Target; import mage.util.CardUtil; /** - * * @author halljared */ public final class AccursedWitch extends CardImpl { @@ -36,7 +35,7 @@ public final class AccursedWitch extends CardImpl { this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = InfectiousCurse.class; + this.secondSideCardClazz = mage.cards.i.InfectiousCurse.class; // Spells your opponents cast that target Accursed Witch cost {1} less to cast. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AccursedWitchSpellsCostReductionEffect())); diff --git a/Mage.Sets/src/mage/cards/a/AfflictedDeserter.java b/Mage.Sets/src/mage/cards/a/AfflictedDeserter.java index 3cbe3dbff4..2b7b3d6b87 100644 --- a/Mage.Sets/src/mage/cards/a/AfflictedDeserter.java +++ b/Mage.Sets/src/mage/cards/a/AfflictedDeserter.java @@ -2,6 +2,7 @@ package mage.cards.a; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,24 +12,22 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.w.WerewolfRansacker; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author BetaSteward */ public final class AfflictedDeserter extends CardImpl { public AfflictedDeserter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = WerewolfRansacker.class; + this.secondSideCardClazz = mage.cards.w.WerewolfRansacker.class; this.power = new MageInt(3); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/a/AnakinSkywalker.java b/Mage.Sets/src/mage/cards/a/AnakinSkywalker.java index be930a31c9..cc479f50a4 100644 --- a/Mage.Sets/src/mage/cards/a/AnakinSkywalker.java +++ b/Mage.Sets/src/mage/cards/a/AnakinSkywalker.java @@ -2,6 +2,7 @@ package mage.cards.a; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; @@ -15,7 +16,6 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.d.DarthVader; import mage.constants.*; import mage.counters.CounterType; import mage.filter.StaticFilters; @@ -27,7 +27,6 @@ import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; /** - * * @author Styxo */ public final class AnakinSkywalker extends CardImpl { @@ -41,7 +40,7 @@ public final class AnakinSkywalker extends CardImpl { this.toughness = new MageInt(4); this.transformable = true; - this.secondSideCardClazz = DarthVader.class; + this.secondSideCardClazz = mage.cards.d.DarthVader.class; // Whenever another creature dies, put a +1/+1 counter on Anakin Skywalker. this.addAbility(new DiesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, true)); diff --git a/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java b/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java index 89be4d3219..1bc606d152 100644 --- a/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java +++ b/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java @@ -2,6 +2,7 @@ package mage.cards.a; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -14,14 +15,12 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.t.TempleOfAclazotz; import mage.constants.CardType; import mage.constants.SuperType; import mage.constants.TargetController; import mage.constants.Zone; /** - * * @author TheElk801 */ public final class ArguelsBloodFast extends CardImpl { @@ -31,7 +30,7 @@ public final class ArguelsBloodFast extends CardImpl { addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = TempleOfAclazotz.class; + this.secondSideCardClazz = mage.cards.t.TempleOfAclazotz.class; // {1}{B}, Pay 2 life: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}{B}")); diff --git a/Mage.Sets/src/mage/cards/a/AvacynianMissionaries.java b/Mage.Sets/src/mage/cards/a/AvacynianMissionaries.java index 6c69bfeeb3..10cdb29561 100644 --- a/Mage.Sets/src/mage/cards/a/AvacynianMissionaries.java +++ b/Mage.Sets/src/mage/cards/a/AvacynianMissionaries.java @@ -2,6 +2,7 @@ package mage.cards.a; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.condition.common.EquippedSourceCondition; @@ -9,27 +10,25 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.l.LunarchInquisitors; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; /** - * * @author fireshoes */ public final class AvacynianMissionaries extends CardImpl { public AvacynianMissionaries(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(3); this.toughness = new MageInt(3); this.transformable = true; - this.secondSideCardClazz = LunarchInquisitors.class; + this.secondSideCardClazz = mage.cards.l.LunarchInquisitors.class; // At the beginning of your end step, if Avacynian Missionaries is equipped, transform it. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/a/AzorsGateway.java b/Mage.Sets/src/mage/cards/a/AzorsGateway.java index ce422328f8..499991f9ea 100644 --- a/Mage.Sets/src/mage/cards/a/AzorsGateway.java +++ b/Mage.Sets/src/mage/cards/a/AzorsGateway.java @@ -4,6 +4,7 @@ package mage.cards.a; import java.util.HashSet; import java.util.Set; import java.util.UUID; + import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -16,7 +17,6 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.s.SanctumOfTheSun; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SuperType; @@ -28,7 +28,6 @@ import mage.target.common.TargetCardInHand; import mage.util.CardUtil; /** - * * @author LevelX2 */ public final class AzorsGateway extends CardImpl { @@ -38,7 +37,7 @@ public final class AzorsGateway extends CardImpl { this.addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = SanctumOfTheSun.class; + this.secondSideCardClazz = mage.cards.s.SanctumOfTheSun.class; // {1}, {T}: Draw a card, then exile a card from your hand. If cards with five or more different converted mana costs are exiled with Azor's Gateway, you gain 5 life, untap Azor's Gateway, and transform it. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/b/BloodlineKeeper.java b/Mage.Sets/src/mage/cards/b/BloodlineKeeper.java index 8069c414cb..b9fc172095 100644 --- a/Mage.Sets/src/mage/cards/b/BloodlineKeeper.java +++ b/Mage.Sets/src/mage/cards/b/BloodlineKeeper.java @@ -2,6 +2,7 @@ package mage.cards.b; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; @@ -15,7 +16,6 @@ import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.l.LordOfLineage; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SubType; @@ -25,7 +25,6 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.permanent.token.VampireToken; /** - * * @author Loki */ public final class BloodlineKeeper extends CardImpl { @@ -44,7 +43,7 @@ public final class BloodlineKeeper extends CardImpl { this.toughness = new MageInt(3); this.transformable = true; - this.secondSideCardClazz = LordOfLineage.class; + this.secondSideCardClazz = mage.cards.l.LordOfLineage.class; this.addAbility(FlyingAbility.getInstance()); // {T}: Create a 2/2 black Vampire creature token with flying. diff --git a/Mage.Sets/src/mage/cards/b/BreakneckRider.java b/Mage.Sets/src/mage/cards/b/BreakneckRider.java index 015fdf0395..f1e8eab11a 100644 --- a/Mage.Sets/src/mage/cards/b/BreakneckRider.java +++ b/Mage.Sets/src/mage/cards/b/BreakneckRider.java @@ -2,6 +2,7 @@ package mage.cards.b; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,25 +12,23 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.n.NeckBreaker; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author fireshoes */ public final class BreakneckRider extends CardImpl { public BreakneckRider(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); this.subtype.add(SubType.HUMAN, SubType.SCOUT, SubType.WEREWOLF); this.power = new MageInt(3); this.toughness = new MageInt(3); - + this.transformable = true; - this.secondSideCardClazz = NeckBreaker.class; + this.secondSideCardClazz = mage.cards.n.NeckBreaker.class; // At the beginning of each upkeep, if no spells were cast last turn, transform Breakneck Rider. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/c/ChosenOfMarkov.java b/Mage.Sets/src/mage/cards/c/ChosenOfMarkov.java index 8a12eb107b..5a31f0d5b8 100644 --- a/Mage.Sets/src/mage/cards/c/ChosenOfMarkov.java +++ b/Mage.Sets/src/mage/cards/c/ChosenOfMarkov.java @@ -2,6 +2,7 @@ package mage.cards.c; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -11,7 +12,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.m.MarkovsServant; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -22,7 +22,6 @@ import mage.filter.predicate.permanent.TappedPredicate; import mage.target.common.TargetControlledPermanent; /** - * * @author Loki */ public final class ChosenOfMarkov extends CardImpl { @@ -34,14 +33,14 @@ public final class ChosenOfMarkov extends CardImpl { } public ChosenOfMarkov(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add(SubType.HUMAN); this.power = new MageInt(2); this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = MarkovsServant.class; + this.secondSideCardClazz = mage.cards.m.MarkovsServant.class; // {tap}, Tap an untapped Vampire you control: Transform Chosen of Markov. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/c/CivilizedScholar.java b/Mage.Sets/src/mage/cards/c/CivilizedScholar.java index 79993fd2c2..775632b928 100644 --- a/Mage.Sets/src/mage/cards/c/CivilizedScholar.java +++ b/Mage.Sets/src/mage/cards/c/CivilizedScholar.java @@ -2,6 +2,7 @@ package mage.cards.c; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -11,7 +12,6 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.h.HomicidalBrute; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; @@ -29,12 +29,12 @@ import mage.watchers.Watcher; public final class CivilizedScholar extends CardImpl { public CivilizedScholar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ADVISOR); this.transformable = true; - this.secondSideCardClazz = HomicidalBrute.class; + this.secondSideCardClazz = mage.cards.h.HomicidalBrute.class; this.power = new MageInt(0); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/c/CloisteredYouth.java b/Mage.Sets/src/mage/cards/c/CloisteredYouth.java index aacd1ce4b9..9e9153a0c2 100644 --- a/Mage.Sets/src/mage/cards/c/CloisteredYouth.java +++ b/Mage.Sets/src/mage/cards/c/CloisteredYouth.java @@ -2,32 +2,31 @@ package mage.cards.c; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.u.UnholyFiend; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author Loki */ public final class CloisteredYouth extends CardImpl { public CloisteredYouth(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.HUMAN); this.power = new MageInt(1); this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = UnholyFiend.class; + this.secondSideCardClazz = mage.cards.u.UnholyFiend.class; // At the beginning of your upkeep, you may transform Cloistered Youth. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/c/ConvictedKiller.java b/Mage.Sets/src/mage/cards/c/ConvictedKiller.java index 513878588f..3cc30aa14d 100644 --- a/Mage.Sets/src/mage/cards/c/ConvictedKiller.java +++ b/Mage.Sets/src/mage/cards/c/ConvictedKiller.java @@ -2,6 +2,7 @@ package mage.cards.c; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,26 +12,24 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.b.BrandedHowler; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author fireshoes */ public final class ConvictedKiller extends CardImpl { public ConvictedKiller(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.power = new MageInt(2); this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = BrandedHowler.class; + this.secondSideCardClazz = mage.cards.b.BrandedHowler.class; // At the beginning of each upkeep, if no spells were cast last turn, transform Convicted Killer. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/c/CryptolithFragment.java b/Mage.Sets/src/mage/cards/c/CryptolithFragment.java index 2980d3aa90..103127f4a4 100644 --- a/Mage.Sets/src/mage/cards/c/CryptolithFragment.java +++ b/Mage.Sets/src/mage/cards/c/CryptolithFragment.java @@ -2,6 +2,7 @@ package mage.cards.c; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.EntersBattlefieldTappedAbility; @@ -13,21 +14,19 @@ import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.AnyColorManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.a.AuroraOfEmrakul; import mage.constants.CardType; import mage.constants.TargetController; /** - * * @author fireshoes */ public final class CryptolithFragment extends CardImpl { public CryptolithFragment(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.transformable = true; - this.secondSideCardClazz = AuroraOfEmrakul.class; + this.secondSideCardClazz = mage.cards.a.AuroraOfEmrakul.class; // Cryptolith Fragment enters the battlefield tapped. this.addAbility(new EntersBattlefieldTappedAbility()); diff --git a/Mage.Sets/src/mage/cards/c/CuriousHomunculus.java b/Mage.Sets/src/mage/cards/c/CuriousHomunculus.java index 183beb3ef6..8770e67a6b 100644 --- a/Mage.Sets/src/mage/cards/c/CuriousHomunculus.java +++ b/Mage.Sets/src/mage/cards/c/CuriousHomunculus.java @@ -2,6 +2,7 @@ package mage.cards.c; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -14,7 +15,6 @@ import mage.abilities.mana.ConditionalColorlessManaAbility; import mage.abilities.mana.builder.common.InstantOrSorcerySpellManaBuilder; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.v.VoraciousReader; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -23,7 +23,6 @@ import mage.game.Game; import mage.players.Player; /** - * * @author fireshoes */ public final class CuriousHomunculus extends CardImpl { @@ -35,7 +34,7 @@ public final class CuriousHomunculus extends CardImpl { this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = VoraciousReader.class; + this.secondSideCardClazz = mage.cards.v.VoraciousReader.class; // {T}: Add {C}. Spend this mana only to cast an instant or sorcery spell. this.addAbility(new ConditionalColorlessManaAbility(new TapSourceCost(), 1, new InstantOrSorcerySpellManaBuilder())); diff --git a/Mage.Sets/src/mage/cards/d/DaringSleuth.java b/Mage.Sets/src/mage/cards/d/DaringSleuth.java index 0d0bef2394..a4fbd3a1c7 100644 --- a/Mage.Sets/src/mage/cards/d/DaringSleuth.java +++ b/Mage.Sets/src/mage/cards/d/DaringSleuth.java @@ -7,7 +7,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.b.BearerOfOverwhelmingTruths; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -18,20 +17,19 @@ import mage.game.events.GameEvent.EventType; import java.util.UUID; /** - * * @author fireshoes */ public final class DaringSleuth extends CardImpl { public DaringSleuth(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ROGUE); this.power = new MageInt(2); this.toughness = new MageInt(1); - + this.transformable = true; - this.secondSideCardClazz = BearerOfOverwhelmingTruths.class; + this.secondSideCardClazz = mage.cards.b.BearerOfOverwhelmingTruths.class; // When you sacrifice a Clue, transform Daring Sleuth. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/d/DaybreakRanger.java b/Mage.Sets/src/mage/cards/d/DaybreakRanger.java index 19f86a0c96..093f520c88 100644 --- a/Mage.Sets/src/mage/cards/d/DaybreakRanger.java +++ b/Mage.Sets/src/mage/cards/d/DaybreakRanger.java @@ -2,6 +2,7 @@ package mage.cards.d; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbility; @@ -16,7 +17,6 @@ import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.n.NightfallPredator; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -26,7 +26,6 @@ import mage.filter.predicate.mageobject.AbilityPredicate; import mage.target.common.TargetCreaturePermanent; /** - * * @author North */ public final class DaybreakRanger extends CardImpl { @@ -38,13 +37,13 @@ public final class DaybreakRanger extends CardImpl { } public DaybreakRanger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARCHER); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = NightfallPredator.class; + this.secondSideCardClazz = mage.cards.n.NightfallPredator.class; this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -67,4 +66,4 @@ public final class DaybreakRanger extends CardImpl { public DaybreakRanger copy() { return new DaybreakRanger(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DelverOfSecrets.java b/Mage.Sets/src/mage/cards/d/DelverOfSecrets.java index 474993fb4c..2b2ea06194 100644 --- a/Mage.Sets/src/mage/cards/d/DelverOfSecrets.java +++ b/Mage.Sets/src/mage/cards/d/DelverOfSecrets.java @@ -2,6 +2,7 @@ package mage.cards.d; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -9,7 +10,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.*; -import mage.cards.i.InsectileAberration; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; @@ -21,13 +21,12 @@ import mage.game.permanent.Permanent; import mage.players.Player; /** - * * @author Alvin */ public final class DelverOfSecrets extends CardImpl { public DelverOfSecrets(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -35,7 +34,7 @@ public final class DelverOfSecrets extends CardImpl { this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = InsectileAberration.class; + this.secondSideCardClazz = mage.cards.i.InsectileAberration.class; // At the beginning of your upkeep, look at the top card of your library. You may reveal that card. If an instant or sorcery card is revealed this way, transform Delver of Secrets. this.addAbility(new TransformAbility()); @@ -53,28 +52,28 @@ public final class DelverOfSecrets extends CardImpl { } class DelverOfSecretsEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterInstantOrSorceryCard(); - + public DelverOfSecretsEffect() { super(Outcome.Benefit); this.staticText = "look at the top card of your library. You may reveal that card. If an instant or sorcery card is revealed this way, transform {this}"; } - + public DelverOfSecretsEffect(final DelverOfSecretsEffect effect) { super(effect); } - + @Override public DelverOfSecretsEffect copy() { return new DelverOfSecretsEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (player != null && sourcePermanent != null) { + if (player != null && sourcePermanent != null) { if (player.getLibrary().hasCards()) { Card card = player.getLibrary().getFromTop(game); Cards cards = new CardsImpl(); @@ -86,10 +85,10 @@ class DelverOfSecretsEffect extends OneShotEffect { return new TransformSourceEffect(true, true).apply(game, source); } } - + } return true; - } + } return false; } } diff --git a/Mage.Sets/src/mage/cards/d/DiligentFarmhand.java b/Mage.Sets/src/mage/cards/d/DiligentFarmhand.java index d659549bca..374c3c905e 100644 --- a/Mage.Sets/src/mage/cards/d/DiligentFarmhand.java +++ b/Mage.Sets/src/mage/cards/d/DiligentFarmhand.java @@ -9,7 +9,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.m.MuscleBurst; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -19,13 +18,12 @@ import mage.target.common.TargetCardInLibrary; import java.util.UUID; /** - * * @author Plopman */ public final class DiligentFarmhand extends CardImpl { public DiligentFarmhand(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.DRUID); @@ -37,7 +35,7 @@ public final class DiligentFarmhand extends CardImpl { ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); // If Diligent Farmhand is in a graveyard, effects from spells named Muscle Burst count it as a card named Muscle Burst. - this.addAbility(MuscleBurst.getCountAsAbility()); + this.addAbility(mage.cards.m.MuscleBurst.getCountAsAbility()); } public DiligentFarmhand(final DiligentFarmhand card) { @@ -48,4 +46,4 @@ public final class DiligentFarmhand extends CardImpl { public DiligentFarmhand copy() { return new DiligentFarmhand(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DocentOfPerfection.java b/Mage.Sets/src/mage/cards/d/DocentOfPerfection.java index f138bce3e9..46b698bb57 100644 --- a/Mage.Sets/src/mage/cards/d/DocentOfPerfection.java +++ b/Mage.Sets/src/mage/cards/d/DocentOfPerfection.java @@ -2,6 +2,7 @@ package mage.cards.d; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; @@ -13,7 +14,6 @@ import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.f.FinalIteration; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -29,7 +29,6 @@ import mage.game.permanent.token.HumanWizardToken; import mage.players.Player; /** - * * @author fireshoes */ public final class DocentOfPerfection extends CardImpl { @@ -43,14 +42,14 @@ public final class DocentOfPerfection extends CardImpl { } public DocentOfPerfection(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); this.subtype.add(SubType.INSECT); this.subtype.add(SubType.HORROR); this.power = new MageInt(5); this.toughness = new MageInt(4); this.transformable = true; - this.secondSideCardClazz = FinalIteration.class; + this.secondSideCardClazz = mage.cards.f.FinalIteration.class; // Flying this.addAbility(FlyingAbility.getInstance()); @@ -107,5 +106,4 @@ class DocentOfPerfectionEffect extends OneShotEffect { } return false; } -} - +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DowsingDagger.java b/Mage.Sets/src/mage/cards/d/DowsingDagger.java index f2693caabe..538bb409c3 100644 --- a/Mage.Sets/src/mage/cards/d/DowsingDagger.java +++ b/Mage.Sets/src/mage/cards/d/DowsingDagger.java @@ -2,6 +2,7 @@ package mage.cards.d; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -15,7 +16,6 @@ import mage.abilities.keyword.TransformAbility; import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.l.LostVale; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; @@ -24,7 +24,6 @@ import mage.target.Target; import mage.target.common.TargetOpponent; /** - * * @author TheElk801 */ public final class DowsingDagger extends CardImpl { @@ -35,7 +34,7 @@ public final class DowsingDagger extends CardImpl { this.subtype.add(SubType.EQUIPMENT); this.transformable = true; - this.secondSideCardClazz = LostVale.class; + this.secondSideCardClazz = mage.cards.l.LostVale.class; // When Dowsing Dagger enters the battlefield, target opponent creates two 0/2 green Plant creature tokens with defender. Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenTargetEffect(new DefenderPlantToken(), 2), false); @@ -62,4 +61,4 @@ public final class DowsingDagger extends CardImpl { public DowsingDagger copy() { return new DowsingDagger(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DuskwatchRecruiter.java b/Mage.Sets/src/mage/cards/d/DuskwatchRecruiter.java index c790d01d34..cd9f699c35 100644 --- a/Mage.Sets/src/mage/cards/d/DuskwatchRecruiter.java +++ b/Mage.Sets/src/mage/cards/d/DuskwatchRecruiter.java @@ -2,6 +2,7 @@ package mage.cards.d; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -14,7 +15,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.k.KrallenhordeHowler; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -35,7 +35,7 @@ public final class DuskwatchRecruiter extends CardImpl { this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = KrallenhordeHowler.class; + this.secondSideCardClazz = mage.cards.k.KrallenhordeHowler.class; this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -61,4 +61,4 @@ public final class DuskwatchRecruiter extends CardImpl { return new DuskwatchRecruiter(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/e/ElbrusTheBindingBlade.java b/Mage.Sets/src/mage/cards/e/ElbrusTheBindingBlade.java index cd5edc770a..d949dd182a 100644 --- a/Mage.Sets/src/mage/cards/e/ElbrusTheBindingBlade.java +++ b/Mage.Sets/src/mage/cards/e/ElbrusTheBindingBlade.java @@ -2,6 +2,7 @@ package mage.cards.e; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -12,7 +13,6 @@ import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.w.WithengarUnbound; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; @@ -22,25 +22,24 @@ import mage.game.Game; import mage.game.permanent.Permanent; /** - * * @author BetaSteward */ public final class ElbrusTheBindingBlade extends CardImpl { public ElbrusTheBindingBlade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{7}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{7}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.EQUIPMENT); this.transformable = true; - this.secondSideCardClazz = WithengarUnbound.class; + this.secondSideCardClazz = mage.cards.w.WithengarUnbound.class; this.addAbility(new TransformAbility()); // Equipped creature gets +1/+0. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0))); // When equipped creature deals combat damage to a player, unattach Elbrus, the Binding Blade, then transform it. - this.addAbility(new DealsDamageToAPlayerAttachedTriggeredAbility(new ElbrusTheBindingBladeEffect(), "equipped", true)); - // Equip {1} + this.addAbility(new DealsDamageToAPlayerAttachedTriggeredAbility(new ElbrusTheBindingBladeEffect(), "equipped", true)); + // Equip {1} this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(1))); } diff --git a/Mage.Sets/src/mage/cards/e/ElusiveTormentor.java b/Mage.Sets/src/mage/cards/e/ElusiveTormentor.java index b173dc3f59..9ea54bd32c 100644 --- a/Mage.Sets/src/mage/cards/e/ElusiveTormentor.java +++ b/Mage.Sets/src/mage/cards/e/ElusiveTormentor.java @@ -2,6 +2,7 @@ package mage.cards.e; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -11,26 +12,24 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.i.InsidiousMist; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; /** - * * @author fireshoes */ public final class ElusiveTormentor extends CardImpl { public ElusiveTormentor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.WIZARD); this.power = new MageInt(4); this.toughness = new MageInt(4); this.transformable = true; - this.secondSideCardClazz = InsidiousMist.class; + this.secondSideCardClazz = mage.cards.i.InsidiousMist.class; // {1}, Discard a card: Transform Elusive Tormentor. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/g/GeierReachBandit.java b/Mage.Sets/src/mage/cards/g/GeierReachBandit.java index d1d7d42b1a..3c5b42f169 100644 --- a/Mage.Sets/src/mage/cards/g/GeierReachBandit.java +++ b/Mage.Sets/src/mage/cards/g/GeierReachBandit.java @@ -2,6 +2,7 @@ package mage.cards.g; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,19 +13,17 @@ import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.v.VildinPackAlpha; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author LevelX2 */ public final class GeierReachBandit extends CardImpl { public GeierReachBandit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ROGUE); this.subtype.add(SubType.WEREWOLF); @@ -32,7 +31,7 @@ public final class GeierReachBandit extends CardImpl { this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = VildinPackAlpha.class; + this.secondSideCardClazz = mage.cards.v.VildinPackAlpha.class; // Haste this.addAbility(HasteAbility.getInstance()); @@ -51,4 +50,4 @@ public final class GeierReachBandit extends CardImpl { public GeierReachBandit copy() { return new GeierReachBandit(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GiselaTheBrokenBlade.java b/Mage.Sets/src/mage/cards/g/GiselaTheBrokenBlade.java index 20d3a59a60..e668ee9d38 100644 --- a/Mage.Sets/src/mage/cards/g/GiselaTheBrokenBlade.java +++ b/Mage.Sets/src/mage/cards/g/GiselaTheBrokenBlade.java @@ -2,6 +2,7 @@ package mage.cards.g; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.condition.common.MeldCondition; @@ -12,7 +13,6 @@ import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.b.BriselaVoiceOfNightmares; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Rarity; @@ -20,13 +20,12 @@ import mage.constants.SuperType; import mage.constants.TargetController; /** - * * @author LevelX2 */ public final class GiselaTheBrokenBlade extends CardImpl { public GiselaTheBrokenBlade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.ANGEL); this.subtype.add(SubType.HORROR); @@ -41,13 +40,13 @@ public final class GiselaTheBrokenBlade extends CardImpl { // Lifelink this.addAbility(LifelinkAbility.getInstance()); - + // At the beginning of your end step, if you both own and control Gisela, the Broken Blade and a creature named Bruna, the Fading Light, exile them, then meld them into Brisela, Voice of Nightmares. this.addAbility(new ConditionalInterveningIfTriggeredAbility( new BeginningOfEndStepTriggeredAbility( new MeldEffect("Bruna, the Fading Light", - new BriselaVoiceOfNightmares(ownerId, - new CardSetInfo("Brisela, Voice of Nightmares", "EMN", "15", Rarity.MYTHIC))), TargetController.YOU, false), + new mage.cards.b.BriselaVoiceOfNightmares(ownerId, + new CardSetInfo("Brisela, Voice of Nightmares", "EMN", "15", Rarity.MYTHIC))), TargetController.YOU, false), new MeldCondition("Bruna, the Fading Light"), "At the beginning of your end step, if you both own and control {this} and a creature named Bruna, the Fading Light, exile them, " + "then meld them into Brisela, Voice of Nightmares.")); @@ -61,4 +60,4 @@ public final class GiselaTheBrokenBlade extends CardImpl { public GiselaTheBrokenBlade copy() { return new GiselaTheBrokenBlade(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GrafRats.java b/Mage.Sets/src/mage/cards/g/GrafRats.java index 339fa36f5b..f4a1101015 100644 --- a/Mage.Sets/src/mage/cards/g/GrafRats.java +++ b/Mage.Sets/src/mage/cards/g/GrafRats.java @@ -2,6 +2,7 @@ package mage.cards.g; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.BeginningOfCombatTriggeredAbility; import mage.abilities.condition.common.MeldCondition; @@ -9,27 +10,25 @@ import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.MeldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.c.ChitteringHost; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Rarity; import mage.constants.TargetController; /** - * * @author emerald000 */ public final class GrafRats extends CardImpl { public GrafRats(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.RAT); this.power = new MageInt(2); this.toughness = new MageInt(1); // At the beginning of combat on your turn, if you both own and control Graf Rats and a creature named Midnight Scavengers, exile them, then meld them into Chittering Host. this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new BeginningOfCombatTriggeredAbility(new MeldEffect("Midnight Scavengers", new ChitteringHost(ownerId, new CardSetInfo("Chittering Host", "EMN", "96", Rarity.COMMON))), TargetController.YOU, false), + new BeginningOfCombatTriggeredAbility(new MeldEffect("Midnight Scavengers", new mage.cards.c.ChitteringHost(ownerId, new CardSetInfo("Chittering Host", "EMN", "96", Rarity.COMMON))), TargetController.YOU, false), new MeldCondition("Midnight Scavengers"), "At the beginning of combat on your turn, if you both own and control {this} and a creature named Midnight Scavengers, exile them, then meld them into Chittering Host.")); } @@ -42,4 +41,4 @@ public final class GrafRats extends CardImpl { public GrafRats copy() { return new GrafRats(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GrizzledOutcasts.java b/Mage.Sets/src/mage/cards/g/GrizzledOutcasts.java index d5093a40a9..e723020473 100644 --- a/Mage.Sets/src/mage/cards/g/GrizzledOutcasts.java +++ b/Mage.Sets/src/mage/cards/g/GrizzledOutcasts.java @@ -2,6 +2,7 @@ package mage.cards.g; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,7 +12,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.k.KrallenhordeWantons; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -22,12 +22,12 @@ import mage.constants.TargetController; public final class GrizzledOutcasts extends CardImpl { public GrizzledOutcasts(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = KrallenhordeWantons.class; + this.secondSideCardClazz = mage.cards.k.KrallenhordeWantons.class; this.power = new MageInt(4); this.toughness = new MageInt(4); @@ -46,4 +46,4 @@ public final class GrizzledOutcasts extends CardImpl { public GrizzledOutcasts copy() { return new GrizzledOutcasts(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java index b749f1410e..40544baff5 100644 --- a/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java +++ b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java @@ -12,7 +12,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.i.ItlimocCradleOfTheSun; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SuperType; @@ -23,7 +22,6 @@ import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.CardTypePredicate; /** - * * @author JRHerlehy */ public final class GrowingRitesOfItlimoc extends CardImpl { @@ -40,7 +38,7 @@ public final class GrowingRitesOfItlimoc extends CardImpl { this.addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = ItlimocCradleOfTheSun.class; + this.secondSideCardClazz = mage.cards.i.ItlimocCradleOfTheSun.class; // When Growing Rites of Itlimoc enters the battlefield, look at the top four cards of your library. // You may reveal a creature card from among them and put it into your hand. @@ -63,4 +61,4 @@ public final class GrowingRitesOfItlimoc extends CardImpl { public GrowingRitesOfItlimoc copy() { return new GrowingRitesOfItlimoc(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/h/HadanasClimb.java b/Mage.Sets/src/mage/cards/h/HadanasClimb.java index 129d75a857..e29d6f4f65 100644 --- a/Mage.Sets/src/mage/cards/h/HadanasClimb.java +++ b/Mage.Sets/src/mage/cards/h/HadanasClimb.java @@ -2,6 +2,7 @@ package mage.cards.h; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.BeginningOfCombatTriggeredAbility; import mage.abilities.condition.common.TargetHasCounterCondition; @@ -11,7 +12,6 @@ import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.w.WingedTempleOfOrazca; import mage.constants.CardType; import mage.constants.SuperType; import mage.constants.TargetController; @@ -19,7 +19,6 @@ import mage.counters.CounterType; import mage.target.common.TargetControlledCreaturePermanent; /** - * * @author LevelX2 */ public final class HadanasClimb extends CardImpl { @@ -30,7 +29,7 @@ public final class HadanasClimb extends CardImpl { this.addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = WingedTempleOfOrazca.class; + this.secondSideCardClazz = mage.cards.w.WingedTempleOfOrazca.class; // At the beginning of combat on your turn, put a +1/+1 counter on target creature you control. Then if that creature has three or more +1/+1 counters on it, transform Hadana's Climb. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/h/HanweirMilitiaCaptain.java b/Mage.Sets/src/mage/cards/h/HanweirMilitiaCaptain.java index 26b44fac7b..2ff6dd1e1c 100644 --- a/Mage.Sets/src/mage/cards/h/HanweirMilitiaCaptain.java +++ b/Mage.Sets/src/mage/cards/h/HanweirMilitiaCaptain.java @@ -2,6 +2,7 @@ package mage.cards.h; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; @@ -10,7 +11,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.w.WestvaleCultLeader; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.ComparisonType; @@ -18,7 +18,6 @@ import mage.constants.TargetController; import mage.filter.common.FilterControlledCreaturePermanent; /** - * * @author fireshoes */ public final class HanweirMilitiaCaptain extends CardImpl { @@ -26,14 +25,14 @@ public final class HanweirMilitiaCaptain extends CardImpl { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("if you control four or more creatures"); public HanweirMilitiaCaptain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); this.power = new MageInt(2); this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = WestvaleCultLeader.class; + this.secondSideCardClazz = mage.cards.w.WestvaleCultLeader.class; // At the beginning of your upkeep, if you control four or more creatures, transform Hanweir Militia Captain. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/h/HanweirWatchkeep.java b/Mage.Sets/src/mage/cards/h/HanweirWatchkeep.java index 463a9b8409..04906ce2c9 100644 --- a/Mage.Sets/src/mage/cards/h/HanweirWatchkeep.java +++ b/Mage.Sets/src/mage/cards/h/HanweirWatchkeep.java @@ -2,6 +2,7 @@ package mage.cards.h; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,7 +13,6 @@ import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.b.BaneOfHanweir; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -23,13 +23,13 @@ import mage.constants.TargetController; public final class HanweirWatchkeep extends CardImpl { public HanweirWatchkeep(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = BaneOfHanweir.class; + this.secondSideCardClazz = mage.cards.b.BaneOfHanweir.class; this.power = new MageInt(1); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/h/HarvestHand.java b/Mage.Sets/src/mage/cards/h/HarvestHand.java index 82c60fd0b1..7661170773 100644 --- a/Mage.Sets/src/mage/cards/h/HarvestHand.java +++ b/Mage.Sets/src/mage/cards/h/HarvestHand.java @@ -2,6 +2,7 @@ package mage.cards.h; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; @@ -10,7 +11,6 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.s.ScroungedScythe; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; @@ -19,19 +19,18 @@ import mage.game.Game; import mage.players.Player; /** - * * @author halljared */ public final class HarvestHand extends CardImpl { public HarvestHand(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); this.subtype.add(SubType.SCARECROW); this.power = new MageInt(2); this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = ScroungedScythe.class; + this.secondSideCardClazz = mage.cards.s.ScroungedScythe.class; // When Harvest Hand dies, return it to the battlefield transformed under your control. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/h/HermitOfTheNatterknolls.java b/Mage.Sets/src/mage/cards/h/HermitOfTheNatterknolls.java index d59c7c8894..a1fe62de6b 100644 --- a/Mage.Sets/src/mage/cards/h/HermitOfTheNatterknolls.java +++ b/Mage.Sets/src/mage/cards/h/HermitOfTheNatterknolls.java @@ -2,6 +2,7 @@ package mage.cards.h; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -15,27 +16,25 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.l.LoneWolfOfTheNatterknolls; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.FilterSpell; /** - * * @author LevelX2 */ public final class HermitOfTheNatterknolls extends CardImpl { public HermitOfTheNatterknolls(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.power = new MageInt(2); this.toughness = new MageInt(3); this.transformable = true; - this.secondSideCardClazz = LoneWolfOfTheNatterknolls.class; + this.secondSideCardClazz = mage.cards.l.LoneWolfOfTheNatterknolls.class; // Whenever an opponent casts a spell during your turn, draw a card. this.addAbility(new ConditionalTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/h/HinterlandLogger.java b/Mage.Sets/src/mage/cards/h/HinterlandLogger.java index 6634e00414..9c7a8da1ab 100644 --- a/Mage.Sets/src/mage/cards/h/HinterlandLogger.java +++ b/Mage.Sets/src/mage/cards/h/HinterlandLogger.java @@ -2,6 +2,7 @@ package mage.cards.h; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,26 +12,24 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.t.TimberShredder; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author fireshoes */ public final class HinterlandLogger extends CardImpl { public HinterlandLogger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.power = new MageInt(2); this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = TimberShredder.class; + this.secondSideCardClazz = mage.cards.t.TimberShredder.class; // At the beginning of each upkeep, if no spells were cast last turn, transform Hinterland Logger. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/h/HuntmasterOfTheFells.java b/Mage.Sets/src/mage/cards/h/HuntmasterOfTheFells.java index 9da3929dfe..f639adeb9a 100644 --- a/Mage.Sets/src/mage/cards/h/HuntmasterOfTheFells.java +++ b/Mage.Sets/src/mage/cards/h/HuntmasterOfTheFells.java @@ -2,6 +2,7 @@ package mage.cards.h; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbilityImpl; @@ -14,7 +15,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.r.RavagerOfTheFells; import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; @@ -22,18 +22,17 @@ import mage.game.permanent.Permanent; import mage.game.permanent.token.WolfToken; /** - * * @author BetaSteward */ public final class HuntmasterOfTheFells extends CardImpl { public HuntmasterOfTheFells(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = RavagerOfTheFells.class; + this.secondSideCardClazz = mage.cards.r.RavagerOfTheFells.class; this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/i/InstigatorGang.java b/Mage.Sets/src/mage/cards/i/InstigatorGang.java index acd165ce41..7573aa13d2 100644 --- a/Mage.Sets/src/mage/cards/i/InstigatorGang.java +++ b/Mage.Sets/src/mage/cards/i/InstigatorGang.java @@ -2,6 +2,7 @@ package mage.cards.i; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -15,7 +16,6 @@ import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.w.WildbloodPack; import mage.constants.*; import mage.filter.common.FilterAttackingCreature; @@ -25,20 +25,20 @@ import mage.filter.common.FilterAttackingCreature; public final class InstigatorGang extends CardImpl { public InstigatorGang(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = WildbloodPack.class; + this.secondSideCardClazz = mage.cards.w.WildbloodPack.class; this.power = new MageInt(2); this.toughness = new MageInt(3); // Attacking creatures you control get +1/+0. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, new FilterAttackingCreature()), - new TransformedCondition(true), "Attacking creatures you control get +1/+0"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new ConditionalContinuousEffect(new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, new FilterAttackingCreature()), + new TransformedCondition(true), "Attacking creatures you control get +1/+0"))); // At the beginning of each upkeep, if no spells were cast last turn, transform Instigator Gang. diff --git a/Mage.Sets/src/mage/cards/i/IsamaruHoundofKonda.java b/Mage.Sets/src/mage/cards/i/IsamaruHoundOfKonda.java similarity index 57% rename from Mage.Sets/src/mage/cards/i/IsamaruHoundofKonda.java rename to Mage.Sets/src/mage/cards/i/IsamaruHoundOfKonda.java index b37e399e45..35296f3e40 100644 --- a/Mage.Sets/src/mage/cards/i/IsamaruHoundofKonda.java +++ b/Mage.Sets/src/mage/cards/i/IsamaruHoundOfKonda.java @@ -3,6 +3,7 @@ package mage.cards.i; import java.util.UUID; + import mage.MageInt; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -11,13 +12,12 @@ import mage.constants.SubType; import mage.constants.SuperType; /** - * * @author Loki */ -public final class IsamaruHoundofKonda extends CardImpl { +public final class IsamaruHoundOfKonda extends CardImpl { - public IsamaruHoundofKonda (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + public IsamaruHoundOfKonda(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HOUND); @@ -25,13 +25,13 @@ public final class IsamaruHoundofKonda extends CardImpl { this.toughness = new MageInt(2); } - public IsamaruHoundofKonda (final IsamaruHoundofKonda card) { + public IsamaruHoundOfKonda(final IsamaruHoundOfKonda card) { super(card); } @Override - public IsamaruHoundofKonda copy() { - return new IsamaruHoundofKonda(this); + public IsamaruHoundOfKonda copy() { + return new IsamaruHoundOfKonda(this); } } diff --git a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java index 365534cf3a..0f735f1380 100644 --- a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java +++ b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java @@ -2,6 +2,7 @@ package mage.cards.j; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.DiesAttachedTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -12,7 +13,6 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.a.AtzalCaveOfEternity; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -24,7 +24,6 @@ import mage.players.Player; import mage.target.TargetPermanent; /** - * * @author LevelX2 */ public final class JourneyToEternity extends CardImpl { @@ -36,7 +35,7 @@ public final class JourneyToEternity extends CardImpl { this.subtype.add(SubType.AURA); this.transformable = true; - this.secondSideCardClazz = AtzalCaveOfEternity.class; + this.secondSideCardClazz = mage.cards.a.AtzalCaveOfEternity.class; // Enchant creature you control TargetPermanent auraTarget = new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED); diff --git a/Mage.Sets/src/mage/cards/k/KessigForgemaster.java b/Mage.Sets/src/mage/cards/k/KessigForgemaster.java index 106b0024a5..c8ffa6637f 100644 --- a/Mage.Sets/src/mage/cards/k/KessigForgemaster.java +++ b/Mage.Sets/src/mage/cards/k/KessigForgemaster.java @@ -2,6 +2,7 @@ package mage.cards.k; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -13,14 +14,12 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.f.FlameheartWerewolf; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.StaticFilters; /** - * * @author LevelX2 */ public final class KessigForgemaster extends CardImpl { @@ -34,7 +33,7 @@ public final class KessigForgemaster extends CardImpl { this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = FlameheartWerewolf.class; + this.secondSideCardClazz = mage.cards.f.FlameheartWerewolf.class; // Whenever Kessig Forgemaster blocks or becomes blocked by a creature, Kessig Forgemaster deals 1 damage to that creature. this.addAbility(new BlocksOrBecomesBlockedTriggeredAbility(new DamageTargetEffect(1, true, "that creature"), diff --git a/Mage.Sets/src/mage/cards/k/KessigProwler.java b/Mage.Sets/src/mage/cards/k/KessigProwler.java index 50bfd528d1..7ead3554b4 100644 --- a/Mage.Sets/src/mage/cards/k/KessigProwler.java +++ b/Mage.Sets/src/mage/cards/k/KessigProwler.java @@ -2,6 +2,7 @@ package mage.cards.k; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -9,26 +10,24 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.s.SinuousPredator; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; /** - * * @author fireshoes */ public final class KessigProwler extends CardImpl { public KessigProwler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.WEREWOLF); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = SinuousPredator.class; + this.secondSideCardClazz = mage.cards.s.SinuousPredator.class; // {4}{G}: Transform Kessig Prowler. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/k/KindlyStranger.java b/Mage.Sets/src/mage/cards/k/KindlyStranger.java index f2456683ba..5a738cd6c2 100644 --- a/Mage.Sets/src/mage/cards/k/KindlyStranger.java +++ b/Mage.Sets/src/mage/cards/k/KindlyStranger.java @@ -2,6 +2,7 @@ package mage.cards.k; import java.util.UUID; + import mage.MageInt; import mage.abilities.condition.common.DeliriumCondition; import mage.abilities.costs.mana.ManaCostsImpl; @@ -10,25 +11,23 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.d.DemonPossessedWitch; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; /** - * * @author fireshoes */ public final class KindlyStranger extends CardImpl { public KindlyStranger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add(SubType.HUMAN); this.power = new MageInt(2); this.toughness = new MageInt(3); this.transformable = true; - this.secondSideCardClazz = DemonPossessedWitch.class; + this.secondSideCardClazz = mage.cards.d.DemonPossessedWitch.class; // Delirium — {2}{B}: Transform Kindly Stranger. Activate this ability only if there are four or more card types among cards in your graveyard. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/k/KruinOutlaw.java b/Mage.Sets/src/mage/cards/k/KruinOutlaw.java index 53b0f8b4b6..452117524b 100644 --- a/Mage.Sets/src/mage/cards/k/KruinOutlaw.java +++ b/Mage.Sets/src/mage/cards/k/KruinOutlaw.java @@ -2,6 +2,7 @@ package mage.cards.k; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,25 +13,23 @@ import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.t.TerrorOfKruinPass; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author North */ public final class KruinOutlaw extends CardImpl { public KruinOutlaw(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ROGUE); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = TerrorOfKruinPass.class; + this.secondSideCardClazz = mage.cards.t.TerrorOfKruinPass.class; this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/k/KytheonHeroOfAkros.java b/Mage.Sets/src/mage/cards/k/KytheonHeroOfAkros.java index e08d2bb278..d420ff39a6 100644 --- a/Mage.Sets/src/mage/cards/k/KytheonHeroOfAkros.java +++ b/Mage.Sets/src/mage/cards/k/KytheonHeroOfAkros.java @@ -2,6 +2,7 @@ package mage.cards.k; import java.util.UUID; + import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; @@ -17,7 +18,6 @@ import mage.abilities.keyword.IndestructibleAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.g.GideonBattleForged; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; @@ -28,7 +28,6 @@ import mage.game.permanent.Permanent; import mage.watchers.common.AttackedOrBlockedThisCombatWatcher; /** - * * @author LevelX2 */ public final class KytheonHeroOfAkros extends CardImpl { @@ -42,7 +41,7 @@ public final class KytheonHeroOfAkros extends CardImpl { this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = GideonBattleForged.class; + this.secondSideCardClazz = mage.cards.g.GideonBattleForged.class; // At end of combat, if Kytheon, Hero of Akros and at least two other creatures attacked this combat, exile Kytheon, // then return him to the battlefield transformed under his owner's control. diff --git a/Mage.Sets/src/mage/cards/l/LambholtElder.java b/Mage.Sets/src/mage/cards/l/LambholtElder.java index 81f15b01a4..d2eabcf469 100644 --- a/Mage.Sets/src/mage/cards/l/LambholtElder.java +++ b/Mage.Sets/src/mage/cards/l/LambholtElder.java @@ -2,6 +2,7 @@ package mage.cards.l; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,19 +12,17 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.s.SilverpeltWerewolf; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author Loki */ public final class LambholtElder extends CardImpl { public LambholtElder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); @@ -31,7 +30,7 @@ public final class LambholtElder extends CardImpl { this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = SilverpeltWerewolf.class; + this.secondSideCardClazz = mage.cards.s.SilverpeltWerewolf.class; // At the beginning of each upkeep, if no spells were cast last turn, transform Lambholt Elder. this.addAbility(new TransformAbility()); @@ -47,4 +46,4 @@ public final class LambholtElder extends CardImpl { public LambholtElder copy() { return new LambholtElder(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/l/LegionsLanding.java b/Mage.Sets/src/mage/cards/l/LegionsLanding.java index b2d43ca2b6..669ac8942f 100644 --- a/Mage.Sets/src/mage/cards/l/LegionsLanding.java +++ b/Mage.Sets/src/mage/cards/l/LegionsLanding.java @@ -2,6 +2,7 @@ package mage.cards.l; import java.util.UUID; + import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.Effect; @@ -11,7 +12,6 @@ import mage.abilities.keyword.TransformAbility; import mage.constants.SuperType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.a.AdantoTheFirstFort; import mage.constants.CardType; import mage.constants.Zone; import mage.game.Game; @@ -19,7 +19,6 @@ import mage.game.events.GameEvent; import mage.game.permanent.token.IxalanVampireToken; /** - * * @author TheElk801 */ public final class LegionsLanding extends CardImpl { @@ -30,7 +29,7 @@ public final class LegionsLanding extends CardImpl { this.addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = AdantoTheFirstFort.class; + this.secondSideCardClazz = mage.cards.a.AdantoTheFirstFort.class; // When Legion's Landing enters the battlefield, create a 1/1 white Vampire creature token with lifelink. this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new IxalanVampireToken()))); @@ -79,4 +78,4 @@ class LegionsLandingTriggeredAbility extends TriggeredAbilityImpl { public String getRule() { return new StringBuilder("When you attack with three or more creatures, ").append(super.getRule()).toString(); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/l/LoneRider.java b/Mage.Sets/src/mage/cards/l/LoneRider.java index dd364058d1..bfc9584854 100644 --- a/Mage.Sets/src/mage/cards/l/LoneRider.java +++ b/Mage.Sets/src/mage/cards/l/LoneRider.java @@ -2,6 +2,7 @@ package mage.cards.l; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.OnEventTriggeredAbility; @@ -13,7 +14,6 @@ import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.i.ItThatRidesAsOne; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.ComparisonType; @@ -21,7 +21,6 @@ import mage.game.events.GameEvent; import mage.watchers.common.PlayerGainedLifeWatcher; /** - * * @author fireshoes */ public final class LoneRider extends CardImpl { @@ -36,7 +35,7 @@ public final class LoneRider extends CardImpl { this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = ItThatRidesAsOne.class; + this.secondSideCardClazz = mage.cards.i.ItThatRidesAsOne.class; // First strike this.addAbility(FirstStrikeAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/l/LoyalCathar.java b/Mage.Sets/src/mage/cards/l/LoyalCathar.java index 16a24c0675..8282b63392 100644 --- a/Mage.Sets/src/mage/cards/l/LoyalCathar.java +++ b/Mage.Sets/src/mage/cards/l/LoyalCathar.java @@ -2,6 +2,7 @@ package mage.cards.l; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; @@ -13,7 +14,6 @@ import mage.abilities.keyword.VigilanceAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.u.UnhallowedCathar; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -23,7 +23,6 @@ import mage.players.Player; import mage.target.targetpointer.FixedTarget; /** - * * @author BetaSteward */ public final class LoyalCathar extends CardImpl { @@ -34,7 +33,7 @@ public final class LoyalCathar extends CardImpl { this.subtype.add(SubType.SOLDIER); this.transformable = true; - this.secondSideCardClazz = UnhallowedCathar.class; + this.secondSideCardClazz = mage.cards.u.UnhallowedCathar.class; this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -116,5 +115,4 @@ class ReturnLoyalCatharEffect extends OneShotEffect { } return true; } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MayorOfAvabruck.java b/Mage.Sets/src/mage/cards/m/MayorOfAvabruck.java index 4800d7c291..eb789d8aca 100644 --- a/Mage.Sets/src/mage/cards/m/MayorOfAvabruck.java +++ b/Mage.Sets/src/mage/cards/m/MayorOfAvabruck.java @@ -2,6 +2,7 @@ package mage.cards.m; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -17,13 +18,11 @@ import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.h.HowlpackAlpha; import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; /** - * * @author North, noxx */ public final class MayorOfAvabruck extends CardImpl { @@ -37,13 +36,13 @@ public final class MayorOfAvabruck extends CardImpl { } public MayorOfAvabruck(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ADVISOR); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = HowlpackAlpha.class; + this.secondSideCardClazz = mage.cards.h.HowlpackAlpha.class; this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/m/MondronenShaman.java b/Mage.Sets/src/mage/cards/m/MondronenShaman.java index aadaae2d69..e1466c5643 100644 --- a/Mage.Sets/src/mage/cards/m/MondronenShaman.java +++ b/Mage.Sets/src/mage/cards/m/MondronenShaman.java @@ -2,6 +2,7 @@ package mage.cards.m; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,20 +12,18 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.t.TovolarsMagehunter; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author North */ public final class MondronenShaman extends CardImpl { public MondronenShaman(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); - this.subtype.add(SubType.HUMAN); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SHAMAN); this.subtype.add(SubType.WEREWOLF); @@ -32,7 +31,7 @@ public final class MondronenShaman extends CardImpl { this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = TovolarsMagehunter.class; + this.secondSideCardClazz = mage.cards.t.TovolarsMagehunter.class; // At the beginning of each upkeep, if no spells were cast last turn, transform Mondronen Shaman. this.addAbility(new TransformAbility()); @@ -50,4 +49,4 @@ public final class MondronenShaman extends CardImpl { public MondronenShaman copy() { return new MondronenShaman(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/n/NecroticOoze.java b/Mage.Sets/src/mage/cards/n/NecroticOoze.java index cb192e769b..47c4ebf5b4 100644 --- a/Mage.Sets/src/mage/cards/n/NecroticOoze.java +++ b/Mage.Sets/src/mage/cards/n/NecroticOoze.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; @@ -15,20 +16,18 @@ import mage.abilities.effects.Effect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.y.YixlidJailer; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; /** - * * @author BetaSteward_at_googlemail.com */ public final class NecroticOoze extends CardImpl { public NecroticOoze(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); this.subtype.add(SubType.OOZE); this.power = new MageInt(4); @@ -90,7 +89,7 @@ public final class NecroticOoze extends CardImpl { public Set isDependentTo(List allEffectsInLayer) { // the dependent classes needs to be an enclosed class for dependent check of continuous effects return allEffectsInLayer.stream() - .filter(effect -> YixlidJailer.class.equals(effect.getClass().getEnclosingClass())) + .filter(effect -> mage.cards.y.YixlidJailer.class.equals(effect.getClass().getEnclosingClass())) .map(Effect::getId) .collect(Collectors.toSet()); diff --git a/Mage.Sets/src/mage/cards/n/NeglectedHeirloom.java b/Mage.Sets/src/mage/cards/n/NeglectedHeirloom.java index 0976c6963d..4a2bf67de6 100644 --- a/Mage.Sets/src/mage/cards/n/NeglectedHeirloom.java +++ b/Mage.Sets/src/mage/cards/n/NeglectedHeirloom.java @@ -2,6 +2,7 @@ package mage.cards.n; import java.util.UUID; + import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; @@ -11,7 +12,6 @@ import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.a.AshmouthBlade; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; @@ -20,17 +20,16 @@ import mage.game.Game; import mage.game.events.GameEvent; /** - * * @author halljared */ public final class NeglectedHeirloom extends CardImpl { public NeglectedHeirloom(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); this.subtype.add(SubType.EQUIPMENT); this.transformable = true; - this.secondSideCardClazz = AshmouthBlade.class; + this.secondSideCardClazz = mage.cards.a.AshmouthBlade.class; // Equipped creature gets +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); diff --git a/Mage.Sets/src/mage/cards/p/PardicFirecat.java b/Mage.Sets/src/mage/cards/p/PardicFirecat.java index 4d4edecd88..b12becb85a 100644 --- a/Mage.Sets/src/mage/cards/p/PardicFirecat.java +++ b/Mage.Sets/src/mage/cards/p/PardicFirecat.java @@ -2,22 +2,21 @@ package mage.cards.p; import java.util.UUID; + import mage.MageInt; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.f.FlameBurst; import mage.constants.CardType; import mage.constants.SubType; /** - * * @author LoneFox */ public final class PardicFirecat extends CardImpl { public PardicFirecat(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.ELEMENTAL); this.subtype.add(SubType.CAT); this.power = new MageInt(2); @@ -26,7 +25,7 @@ public final class PardicFirecat extends CardImpl { // Haste this.addAbility(HasteAbility.getInstance()); // If Pardic Firecat is in a graveyard, effects from spells named Flame Burst count it as a card named Flame Burst. - this.addAbility(FlameBurst.getCountAsAbility()); + this.addAbility(mage.cards.f.FlameBurst.getCountAsAbility()); } public PardicFirecat(final PardicFirecat card) { @@ -37,4 +36,4 @@ public final class PardicFirecat extends CardImpl { public PardicFirecat copy() { return new PardicFirecat(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PathOfMettle.java b/Mage.Sets/src/mage/cards/p/PathOfMettle.java index 10ec5e2d64..e2a2759b77 100644 --- a/Mage.Sets/src/mage/cards/p/PathOfMettle.java +++ b/Mage.Sets/src/mage/cards/p/PathOfMettle.java @@ -2,6 +2,7 @@ package mage.cards.p; import java.util.UUID; + import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DamageAllEffect; @@ -13,7 +14,6 @@ import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.m.MetzaliTowerOfTriumph; import mage.constants.CardType; import mage.constants.SuperType; import mage.constants.Zone; @@ -24,7 +24,6 @@ import mage.game.Game; import mage.game.events.GameEvent; /** - * * @author LevelX2 */ public final class PathOfMettle extends CardImpl { @@ -46,7 +45,7 @@ public final class PathOfMettle extends CardImpl { this.addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = MetzaliTowerOfTriumph.class; + this.secondSideCardClazz = mage.cards.m.MetzaliTowerOfTriumph.class; // When Path of Mettle enters the battlefield, it deals 1 damage to each creature that doesn't have first strike, double strike, vigilance, or haste. this.addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect(1, filter))); @@ -118,5 +117,4 @@ class PathOfMettleTriggeredAbility extends TriggeredAbilityImpl { public String getRule() { return "Whenever you attack with at least two creatures that have first strike, double strike, vigilance, and/or haste, transform Path of Mettle"; } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PiousEvangel.java b/Mage.Sets/src/mage/cards/p/PiousEvangel.java index 3e95888ccb..3cf2046a8a 100644 --- a/Mage.Sets/src/mage/cards/p/PiousEvangel.java +++ b/Mage.Sets/src/mage/cards/p/PiousEvangel.java @@ -2,6 +2,7 @@ package mage.cards.p; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; @@ -14,7 +15,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.w.WaywardDisciple; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -25,7 +25,6 @@ import mage.filter.predicate.permanent.AnotherPredicate; import mage.target.common.TargetControlledPermanent; /** - * * @author fireshoes */ public final class PiousEvangel extends CardImpl { @@ -38,14 +37,14 @@ public final class PiousEvangel extends CardImpl { } public PiousEvangel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); this.power = new MageInt(2); this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = WaywardDisciple.class; + this.secondSideCardClazz = mage.cards.w.WaywardDisciple.class; // Whenever Pious Evangel or another creature enters the battlefield under your control, you gain 1 life. this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), filter)); @@ -66,4 +65,4 @@ public final class PiousEvangel extends CardImpl { public PiousEvangel copy() { return new PiousEvangel(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/ProfaneProcession.java b/Mage.Sets/src/mage/cards/p/ProfaneProcession.java index 54ed2bce42..67d0fa8434 100644 --- a/Mage.Sets/src/mage/cards/p/ProfaneProcession.java +++ b/Mage.Sets/src/mage/cards/p/ProfaneProcession.java @@ -2,6 +2,7 @@ package mage.cards.p; import java.util.UUID; + import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -12,7 +13,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.t.TombOfTheDuskRose; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SuperType; @@ -24,7 +24,6 @@ import mage.target.common.TargetCreaturePermanent; import mage.util.CardUtil; /** - * * @author LevelX2 */ public final class ProfaneProcession extends CardImpl { @@ -35,7 +34,7 @@ public final class ProfaneProcession extends CardImpl { this.addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = TombOfTheDuskRose.class; + this.secondSideCardClazz = mage.cards.t.TombOfTheDuskRose.class; // {3}{W}{B}: Exile target creature. Then if there are three or more cards exiled with Profane Procession, transform it. this.addAbility(new TransformAbility()); @@ -86,4 +85,4 @@ class ProfaneProcessionEffect extends OneShotEffect { } return false; } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RavenousDemon.java b/Mage.Sets/src/mage/cards/r/RavenousDemon.java index 32268f4dcf..d9d4e51e65 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousDemon.java +++ b/Mage.Sets/src/mage/cards/r/RavenousDemon.java @@ -2,6 +2,7 @@ package mage.cards.r; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; @@ -9,7 +10,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.a.ArchdemonOfGreed; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -18,7 +18,6 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.target.common.TargetControlledPermanent; /** - * * @author intimidatingant */ public final class RavenousDemon extends CardImpl { @@ -29,11 +28,11 @@ public final class RavenousDemon extends CardImpl { } public RavenousDemon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.subtype.add(SubType.DEMON); this.transformable = true; - this.secondSideCardClazz = ArchdemonOfGreed.class; + this.secondSideCardClazz = mage.cards.a.ArchdemonOfGreed.class; this.power = new MageInt(4); this.toughness = new MageInt(4); @@ -51,4 +50,4 @@ public final class RavenousDemon extends CardImpl { public RavenousDemon copy() { return new RavenousDemon(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RecklessWaif.java b/Mage.Sets/src/mage/cards/r/RecklessWaif.java index 04e5cca06c..111ae634b7 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessWaif.java +++ b/Mage.Sets/src/mage/cards/r/RecklessWaif.java @@ -2,6 +2,7 @@ package mage.cards.r; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,7 +12,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.m.MercilessPredator; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -22,13 +22,13 @@ import mage.constants.TargetController; public final class RecklessWaif extends CardImpl { public RecklessWaif(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ROGUE); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = MercilessPredator.class; + this.secondSideCardClazz = mage.cards.m.MercilessPredator.class; this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java b/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java index e2d5f375dd..dcecae03c6 100644 --- a/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java +++ b/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java @@ -2,6 +2,7 @@ package mage.cards.s; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -19,7 +20,6 @@ import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.w.WerewolfOfAncientHunger; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; @@ -27,13 +27,12 @@ import mage.constants.TargetController; import mage.constants.Zone; /** - * * @author fireshoes */ public final class SageOfAncientLore extends CardImpl { public SageOfAncientLore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SHAMAN); this.subtype.add(SubType.WEREWOLF); @@ -41,13 +40,13 @@ public final class SageOfAncientLore extends CardImpl { this.toughness = new MageInt(0); this.transformable = true; - this.secondSideCardClazz = WerewolfOfAncientHunger.class; + this.secondSideCardClazz = mage.cards.w.WerewolfOfAncientHunger.class; // Sage of Ancient Lore's power and toughness are each equal to the number of cards in your hand. - DynamicValue xValue= new CardsInControllerHandCount(); - this.addAbility(new SimpleStaticAbility(Zone.ALL, + DynamicValue xValue = new CardsInControllerHandCount(); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new ConditionalContinuousEffect(new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame), - new TransformedCondition(true), "{this}'s power and toughness are each equal to the total number of cards in your hand"))); + new TransformedCondition(true), "{this}'s power and toughness are each equal to the total number of cards in your hand"))); // When Sage of Ancient Lore enters the battlefield, draw a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); diff --git a/Mage.Sets/src/mage/cards/s/ScornedVillager.java b/Mage.Sets/src/mage/cards/s/ScornedVillager.java index 87ba993c59..a6a5f9529c 100644 --- a/Mage.Sets/src/mage/cards/s/ScornedVillager.java +++ b/Mage.Sets/src/mage/cards/s/ScornedVillager.java @@ -2,6 +2,7 @@ package mage.cards.s; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,19 +13,17 @@ import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.GreenManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.m.MoonscarredWerewolf; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author North */ public final class ScornedVillager extends CardImpl { public ScornedVillager(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); @@ -32,7 +31,7 @@ public final class ScornedVillager extends CardImpl { this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = MoonscarredWerewolf.class; + this.secondSideCardClazz = mage.cards.m.MoonscarredWerewolf.class; // {tap}: Add {G}. this.addAbility(new GreenManaAbility()); diff --git a/Mage.Sets/src/mage/cards/s/SealAway.java b/Mage.Sets/src/mage/cards/s/SealAway.java index 0907d95783..ebf5fdcdb8 100644 --- a/Mage.Sets/src/mage/cards/s/SealAway.java +++ b/Mage.Sets/src/mage/cards/s/SealAway.java @@ -11,7 +11,6 @@ import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.c.CastOut; import mage.constants.CardType; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; @@ -21,7 +20,7 @@ import mage.target.TargetPermanent; /** * @author JRHerlehy - * Created on 4/4/18. + * Created on 4/4/18. */ public final class SealAway extends CardImpl { diff --git a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java index 616efed314..477cbbbd2e 100644 --- a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java +++ b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java @@ -2,6 +2,7 @@ package mage.cards.s; import java.util.UUID; + import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,7 +13,6 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.CardsImpl; -import mage.cards.a.AzcantaTheSunkenRuin; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SuperType; @@ -22,7 +22,6 @@ import mage.game.Game; import mage.players.Player; /** - * * @author LevelX2 */ public final class SearchForAzcanta extends CardImpl { @@ -31,7 +30,7 @@ public final class SearchForAzcanta extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); this.transformable = true; - this.secondSideCardClazz = AzcantaTheSunkenRuin.class; + this.secondSideCardClazz = mage.cards.a.AzcantaTheSunkenRuin.class; this.addSuperType(SuperType.LEGENDARY); @@ -89,4 +88,4 @@ class SearchForAzcantaLookLibraryEffect extends OneShotEffect { } return false; } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/ShrillHowler.java b/Mage.Sets/src/mage/cards/s/ShrillHowler.java index e59f210d2f..f564e981d4 100644 --- a/Mage.Sets/src/mage/cards/s/ShrillHowler.java +++ b/Mage.Sets/src/mage/cards/s/ShrillHowler.java @@ -2,6 +2,7 @@ package mage.cards.s; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -11,26 +12,24 @@ import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesWithLessPowe import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.h.HowlingChorus; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; /** - * * @author LevelX2 */ public final class ShrillHowler extends CardImpl { public ShrillHowler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.WEREWOLF); this.subtype.add(SubType.HORROR); this.power = new MageInt(3); this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = HowlingChorus.class; + this.secondSideCardClazz = mage.cards.h.HowlingChorus.class; // Creatures with power less than Shrill Howler's power can't block it. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByCreaturesWithLessPowerEffect())); @@ -49,4 +48,4 @@ public final class ShrillHowler extends CardImpl { public ShrillHowler copy() { return new ShrillHowler(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SmolderingWerewolf.java b/Mage.Sets/src/mage/cards/s/SmolderingWerewolf.java index c9d56f6dd6..1421ef684b 100644 --- a/Mage.Sets/src/mage/cards/s/SmolderingWerewolf.java +++ b/Mage.Sets/src/mage/cards/s/SmolderingWerewolf.java @@ -2,6 +2,7 @@ package mage.cards.s; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -13,27 +14,25 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.e.EruptingDreadwolf; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; import mage.target.common.TargetCreaturePermanent; /** - * * @author fireshoes */ public final class SmolderingWerewolf extends CardImpl { public SmolderingWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.WEREWOLF); this.subtype.add(SubType.HORROR); this.power = new MageInt(3); this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = EruptingDreadwolf.class; + this.secondSideCardClazz = mage.cards.e.EruptingDreadwolf.class; // When Smoldering Werewolf enters the battlefield, it deals 1 damage to each of up to two target creatures. Effect effect = new DamageTargetEffect(1); @@ -55,4 +54,4 @@ public final class SmolderingWerewolf extends CardImpl { public SmolderingWerewolf copy() { return new SmolderingWerewolf(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SolitaryHunter.java b/Mage.Sets/src/mage/cards/s/SolitaryHunter.java index 917b5e1e71..fd65f0f58a 100644 --- a/Mage.Sets/src/mage/cards/s/SolitaryHunter.java +++ b/Mage.Sets/src/mage/cards/s/SolitaryHunter.java @@ -2,6 +2,7 @@ package mage.cards.s; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,19 +12,17 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.o.OneOfThePack; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author LevelX2 */ public final class SolitaryHunter extends CardImpl { public SolitaryHunter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); this.subtype.add(SubType.WEREWOLF); @@ -32,7 +31,7 @@ public final class SolitaryHunter extends CardImpl { this.toughness = new MageInt(4); this.transformable = true; - this.secondSideCardClazz = OneOfThePack.class; + this.secondSideCardClazz = mage.cards.o.OneOfThePack.class; // At the beginning of each upkeep, if no spells were cast last turn, transform Solitary Hunter. this.addAbility(new TransformAbility()); @@ -48,4 +47,4 @@ public final class SolitaryHunter extends CardImpl { public SolitaryHunter copy() { return new SolitaryHunter(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SoulSeizer.java b/Mage.Sets/src/mage/cards/s/SoulSeizer.java index 04af0f1183..f578200ea0 100644 --- a/Mage.Sets/src/mage/cards/s/SoulSeizer.java +++ b/Mage.Sets/src/mage/cards/s/SoulSeizer.java @@ -2,6 +2,7 @@ package mage.cards.s; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -10,7 +11,6 @@ import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.g.GhastlyHaunting; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; @@ -26,17 +26,16 @@ import mage.players.Player; import mage.target.common.TargetCreaturePermanent; /** - * * @author BetaSteward */ public final class SoulSeizer extends CardImpl { public SoulSeizer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); this.subtype.add(SubType.SPIRIT); this.transformable = true; - this.secondSideCardClazz = GhastlyHaunting.class; + this.secondSideCardClazz = mage.cards.g.GhastlyHaunting.class; this.power = new MageInt(1); this.toughness = new MageInt(3); @@ -80,7 +79,7 @@ class SoulSeizerTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; + DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { Player opponent = game.getPlayer(event.getPlayerId()); if (opponent != null) { @@ -116,7 +115,7 @@ class SoulSeizerEffect extends OneShotEffect { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null && permanent.isTransformable()) { if (permanent.transform(game)) { - game.informPlayers(new StringBuilder(permanent.getName()).append(" transforms into ").append(permanent.getSecondCardFace().getName()).toString()); + game.informPlayers(new StringBuilder(permanent.getName()).append(" transforms into ").append(permanent.getSecondCardFace().getName()).toString()); Permanent attachTo = game.getPermanent(targetPointer.getFirst(game, source)); if (attachTo != null) { return attachTo.addAttachment(source.getSourceId(), game); diff --git a/Mage.Sets/src/mage/cards/s/StartledAwake.java b/Mage.Sets/src/mage/cards/s/StartledAwake.java index 9aefc281a3..ac44405668 100644 --- a/Mage.Sets/src/mage/cards/s/StartledAwake.java +++ b/Mage.Sets/src/mage/cards/s/StartledAwake.java @@ -2,6 +2,7 @@ package mage.cards.s; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -11,7 +12,6 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.p.PersistentNightmare; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; @@ -20,16 +20,15 @@ import mage.players.Player; import mage.target.common.TargetOpponent; /** - * * @author LevelX2 */ public final class StartledAwake extends CardImpl { public StartledAwake(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}"); this.transformable = true; - this.secondSideCardClazz = PersistentNightmare.class; + this.secondSideCardClazz = mage.cards.p.PersistentNightmare.class; // Target opponent puts the top thirteen cards of their library into their graveyard. this.getSpellAbility().addTarget(new TargetOpponent()); @@ -83,4 +82,4 @@ class StartledAwakeReturnTransformedEffect extends OneShotEffect { } return false; } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/StormTheVault.java b/Mage.Sets/src/mage/cards/s/StormTheVault.java index 968f3b72d5..0cdff1b9da 100644 --- a/Mage.Sets/src/mage/cards/s/StormTheVault.java +++ b/Mage.Sets/src/mage/cards/s/StormTheVault.java @@ -15,7 +15,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.v.VaultOfCatlacan; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SuperType; @@ -25,7 +24,6 @@ import mage.game.Game; import mage.game.permanent.token.TreasureToken; /** - * * @author LevelX2 */ public final class StormTheVault extends CardImpl { @@ -36,7 +34,7 @@ public final class StormTheVault extends CardImpl { this.addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = VaultOfCatlacan.class; + this.secondSideCardClazz = mage.cards.v.VaultOfCatlacan.class; // Whenever one or more creatures you control deal combat damage to a player, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color." this.addAbility(new ControlledCreaturesDealCombatDamagePlayerTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); @@ -51,7 +49,6 @@ public final class StormTheVault extends CardImpl { } - public StormTheVault(final StormTheVault card) { super(card); } @@ -60,4 +57,4 @@ public final class StormTheVault extends CardImpl { public StormTheVault copy() { return new StormTheVault(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/TangleclawWerewolf.java b/Mage.Sets/src/mage/cards/t/TangleclawWerewolf.java index 87d8e0b77c..4c48ff2fa3 100644 --- a/Mage.Sets/src/mage/cards/t/TangleclawWerewolf.java +++ b/Mage.Sets/src/mage/cards/t/TangleclawWerewolf.java @@ -2,6 +2,7 @@ package mage.cards.t; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -11,27 +12,25 @@ import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.f.FibrousEntangler; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; /** - * * @author LevelX2 */ public final class TangleclawWerewolf extends CardImpl { public TangleclawWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); this.subtype.add(SubType.WEREWOLF); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); this.toughness = new MageInt(4); this.transformable = true; - this.secondSideCardClazz = FibrousEntangler.class; + this.secondSideCardClazz = mage.cards.f.FibrousEntangler.class; // Tangleclaw Werewolf can block an additional creature each combat. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAdditionalCreatureEffect(Duration.WhileOnBattlefield, 1))); diff --git a/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java index b87140dc64..10635ad04e 100644 --- a/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java +++ b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java @@ -2,6 +2,7 @@ package mage.cards.t; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; @@ -15,7 +16,6 @@ import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.s.SpiresOfOrazca; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.TargetController; @@ -25,7 +25,6 @@ import mage.filter.common.FilterLandPermanent; import mage.target.common.TargetCardInLibrary; /** - * * @author TheElk801 */ public final class ThaumaticCompass extends CardImpl { @@ -33,7 +32,7 @@ public final class ThaumaticCompass extends CardImpl { public ThaumaticCompass(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); this.transformable = true; - this.secondSideCardClazz = SpiresOfOrazca.class; + this.secondSideCardClazz = mage.cards.s.SpiresOfOrazca.class; // {3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, diff --git a/Mage.Sets/src/mage/cards/t/ThingInTheIce.java b/Mage.Sets/src/mage/cards/t/ThingInTheIce.java index ef09626c5d..d6b018e765 100644 --- a/Mage.Sets/src/mage/cards/t/ThingInTheIce.java +++ b/Mage.Sets/src/mage/cards/t/ThingInTheIce.java @@ -2,6 +2,7 @@ package mage.cards.t; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; @@ -16,7 +17,6 @@ import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.a.AwokenHorror; import mage.constants.CardType; import mage.constants.SubType; import mage.counters.CounterType; @@ -25,7 +25,6 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; /** - * * @author fireshoes */ public final class ThingInTheIce extends CardImpl { @@ -39,13 +38,13 @@ public final class ThingInTheIce extends CardImpl { } public ThingInTheIce(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.HORROR); this.power = new MageInt(0); this.toughness = new MageInt(4); this.transformable = true; - this.secondSideCardClazz = AwokenHorror.class; + this.secondSideCardClazz = mage.cards.a.AwokenHorror.class; // Defender this.addAbility(DefenderAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/t/ThousandleggedKami.java b/Mage.Sets/src/mage/cards/t/ThousandLeggedKami.java similarity index 58% rename from Mage.Sets/src/mage/cards/t/ThousandleggedKami.java rename to Mage.Sets/src/mage/cards/t/ThousandLeggedKami.java index 2d3e3b1c8f..adeca1a8e9 100644 --- a/Mage.Sets/src/mage/cards/t/ThousandleggedKami.java +++ b/Mage.Sets/src/mage/cards/t/ThousandLeggedKami.java @@ -3,6 +3,7 @@ package mage.cards.t; import java.util.UUID; + import mage.MageInt; import mage.abilities.keyword.SoulshiftAbility; import mage.cards.CardImpl; @@ -13,10 +14,10 @@ import mage.constants.SubType; /** * @author Loki */ -public final class ThousandleggedKami extends CardImpl { +public final class ThousandLeggedKami extends CardImpl { - public ThousandleggedKami(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{G}{G}"); + public ThousandLeggedKami(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{G}{G}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(6); @@ -24,13 +25,13 @@ public final class ThousandleggedKami extends CardImpl { this.addAbility(new SoulshiftAbility(7)); } - public ThousandleggedKami(final ThousandleggedKami card) { + public ThousandLeggedKami(final ThousandLeggedKami card) { super(card); } @Override - public ThousandleggedKami copy() { - return new ThousandleggedKami(this); + public ThousandLeggedKami copy() { + return new ThousandLeggedKami(this); } } diff --git a/Mage.Sets/src/mage/cards/t/ThrabenGargoyle.java b/Mage.Sets/src/mage/cards/t/ThrabenGargoyle.java index 50a632e756..199eb7f3c2 100644 --- a/Mage.Sets/src/mage/cards/t/ThrabenGargoyle.java +++ b/Mage.Sets/src/mage/cards/t/ThrabenGargoyle.java @@ -2,6 +2,7 @@ package mage.cards.t; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; @@ -10,25 +11,23 @@ import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.s.StonewingAntagonizer; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; /** - * * @author fireshoes */ public final class ThrabenGargoyle extends CardImpl { public ThrabenGargoyle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}"); this.subtype.add(SubType.GARGOYLE); this.power = new MageInt(2); this.toughness = new MageInt(2); this.transformable = true; - this.secondSideCardClazz = StonewingAntagonizer.class; + this.secondSideCardClazz = mage.cards.s.StonewingAntagonizer.class; // Defender this.addAbility(DefenderAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/t/TormentedPariah.java b/Mage.Sets/src/mage/cards/t/TormentedPariah.java index 2dbaaaac84..468086a78b 100644 --- a/Mage.Sets/src/mage/cards/t/TormentedPariah.java +++ b/Mage.Sets/src/mage/cards/t/TormentedPariah.java @@ -2,6 +2,7 @@ package mage.cards.t; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,7 +12,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.r.RampagingWerewolf; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -22,13 +22,13 @@ import mage.constants.TargetController; public final class TormentedPariah extends CardImpl { public TormentedPariah(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = RampagingWerewolf.class; + this.secondSideCardClazz = mage.cards.r.RampagingWerewolf.class; this.power = new MageInt(3); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/t/TownGossipmonger.java b/Mage.Sets/src/mage/cards/t/TownGossipmonger.java index a3f2152893..8d53546072 100644 --- a/Mage.Sets/src/mage/cards/t/TownGossipmonger.java +++ b/Mage.Sets/src/mage/cards/t/TownGossipmonger.java @@ -2,6 +2,7 @@ package mage.cards.t; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -11,7 +12,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.i.IncitedRabble; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -21,11 +21,10 @@ import mage.filter.predicate.permanent.TappedPredicate; import mage.target.common.TargetControlledCreaturePermanent; /** - * * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com) */ public final class TownGossipmonger extends CardImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creature you control"); static { @@ -33,19 +32,19 @@ public final class TownGossipmonger extends CardImpl { } public TownGossipmonger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.subtype.add(SubType.HUMAN); this.power = new MageInt(1); this.toughness = new MageInt(1); - + this.transformable = true; - this.secondSideCardClazz = IncitedRabble.class; + this.secondSideCardClazz = mage.cards.i.IncitedRabble.class; // {T}, Tap an untapped creature you control: Transform Town Gossipmonger. this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(true), new TapSourceCost()); ability.addCost(new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))); - this.addAbility(ability); + this.addAbility(ability); } public TownGossipmonger(final TownGossipmonger card) { @@ -56,4 +55,4 @@ public final class TownGossipmonger extends CardImpl { public TownGossipmonger copy() { return new TownGossipmonger(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java index c29c57a9a2..e69e0dc634 100644 --- a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java +++ b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java @@ -2,6 +2,7 @@ package mage.cards.v; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -13,7 +14,6 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.s.SpitfireBastion; import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; @@ -29,7 +29,6 @@ import mage.target.targetpointer.FixedTarget; import mage.watchers.common.CastSpellLastTurnWatcher; /** - * * @author TheElk801 */ public final class VancesBlastingCannons extends CardImpl { @@ -39,7 +38,7 @@ public final class VancesBlastingCannons extends CardImpl { this.addSuperType(SuperType.LEGENDARY); this.transformable = true; - this.secondSideCardClazz = SpitfireBastion.class; + this.secondSideCardClazz = mage.cards.s.SpitfireBastion.class; // At the beginning of your upkeep, exile the top card of your library. If it's a nonland card, you may cast that card this turn. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new VancesBlastingCannonsExileEffect(), TargetController.YOU, false)); diff --git a/Mage.Sets/src/mage/cards/v/VildinPackOutcast.java b/Mage.Sets/src/mage/cards/v/VildinPackOutcast.java index 05c7691469..bba28333bc 100644 --- a/Mage.Sets/src/mage/cards/v/VildinPackOutcast.java +++ b/Mage.Sets/src/mage/cards/v/VildinPackOutcast.java @@ -2,6 +2,7 @@ package mage.cards.v; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -11,27 +12,25 @@ import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.d.DronepackKindred; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; /** - * * @author fireshoes */ public final class VildinPackOutcast extends CardImpl { public VildinPackOutcast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); this.subtype.add(SubType.WEREWOLF); this.subtype.add(SubType.HORROR); this.power = new MageInt(4); this.toughness = new MageInt(4); this.transformable = true; - this.secondSideCardClazz = DronepackKindred.class; + this.secondSideCardClazz = mage.cards.d.DronepackKindred.class; // Trample this.addAbility(TrampleAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/v/VillageIronsmith.java b/Mage.Sets/src/mage/cards/v/VillageIronsmith.java index 2ab6e27cde..ab4b8c6879 100644 --- a/Mage.Sets/src/mage/cards/v/VillageIronsmith.java +++ b/Mage.Sets/src/mage/cards/v/VillageIronsmith.java @@ -2,6 +2,7 @@ package mage.cards.v; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,7 +13,6 @@ import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.i.Ironfang; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -23,12 +23,12 @@ import mage.constants.TargetController; public final class VillageIronsmith extends CardImpl { public VillageIronsmith(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = Ironfang.class; + this.secondSideCardClazz = mage.cards.i.Ironfang.class; this.power = new MageInt(1); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/v/VillageMessenger.java b/Mage.Sets/src/mage/cards/v/VillageMessenger.java index ef0a93f894..73e15f3301 100644 --- a/Mage.Sets/src/mage/cards/v/VillageMessenger.java +++ b/Mage.Sets/src/mage/cards/v/VillageMessenger.java @@ -2,6 +2,7 @@ package mage.cards.v; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -12,26 +13,24 @@ import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.m.MoonriseIntruder; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; /** - * * @author fireshoes */ public final class VillageMessenger extends CardImpl { public VillageMessenger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.power = new MageInt(1); this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = MoonriseIntruder.class; + this.secondSideCardClazz = mage.cards.m.MoonriseIntruder.class; // Haste this.addAbility(HasteAbility.getInstance()); @@ -50,4 +49,4 @@ public final class VillageMessenger extends CardImpl { public VillageMessenger copy() { return new VillageMessenger(this); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/v/VillagersOfEstwald.java b/Mage.Sets/src/mage/cards/v/VillagersOfEstwald.java index a320c5a6f3..e8e5d20c83 100644 --- a/Mage.Sets/src/mage/cards/v/VillagersOfEstwald.java +++ b/Mage.Sets/src/mage/cards/v/VillagersOfEstwald.java @@ -2,6 +2,7 @@ package mage.cards.v; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -11,7 +12,6 @@ import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.h.HowlpackOfEstwald; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -22,12 +22,12 @@ import mage.constants.TargetController; public final class VillagersOfEstwald extends CardImpl { public VillagersOfEstwald(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); this.transformable = true; - this.secondSideCardClazz = HowlpackOfEstwald.class; + this.secondSideCardClazz = mage.cards.h.HowlpackOfEstwald.class; this.power = new MageInt(2); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/v/VoldarenPariah.java b/Mage.Sets/src/mage/cards/v/VoldarenPariah.java index 1373589496..1f4be360d2 100644 --- a/Mage.Sets/src/mage/cards/v/VoldarenPariah.java +++ b/Mage.Sets/src/mage/cards/v/VoldarenPariah.java @@ -2,6 +2,7 @@ package mage.cards.v; import java.util.UUID; + import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; @@ -12,7 +13,6 @@ import mage.abilities.keyword.MadnessAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.a.AbolisherOfBloodlines; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -21,7 +21,6 @@ import mage.filter.predicate.permanent.AnotherPredicate; import mage.target.common.TargetControlledPermanent; /** - * * @author fireshoes */ public final class VoldarenPariah extends CardImpl { @@ -33,14 +32,14 @@ public final class VoldarenPariah extends CardImpl { } public VoldarenPariah(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.HORROR); this.power = new MageInt(3); this.toughness = new MageInt(3); this.transformable = true; - this.secondSideCardClazz = AbolisherOfBloodlines.class; + this.secondSideCardClazz = mage.cards.a.AbolisherOfBloodlines.class; // Flying this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java b/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java index 86dc68633b..f806356498 100644 --- a/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java +++ b/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java @@ -2,6 +2,7 @@ package mage.cards.w; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.PayLifeCost; @@ -15,7 +16,6 @@ import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.o.OrmendahlProfanePrince; import mage.constants.CardType; import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; @@ -23,7 +23,6 @@ import mage.game.permanent.token.HumanClericToken; import mage.target.common.TargetControlledPermanent; /** - * * @author fireshoes */ public final class WestvaleAbbey extends CardImpl { @@ -32,7 +31,7 @@ public final class WestvaleAbbey extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.transformable = true; - this.secondSideCardClazz = OrmendahlProfanePrince.class; + this.secondSideCardClazz = mage.cards.o.OrmendahlProfanePrince.class; // {T}: Add {C}. this.addAbility(new ColorlessManaAbility()); diff --git a/Mage.Sets/src/mage/cards/w/WolfbittenCaptive.java b/Mage.Sets/src/mage/cards/w/WolfbittenCaptive.java index b9880a923a..d56a5d9e38 100644 --- a/Mage.Sets/src/mage/cards/w/WolfbittenCaptive.java +++ b/Mage.Sets/src/mage/cards/w/WolfbittenCaptive.java @@ -2,6 +2,7 @@ package mage.cards.w; import java.util.UUID; + import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -14,17 +15,15 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.k.KrallenhordeKiller; import mage.constants.*; /** - * * @author Loki */ public final class WolfbittenCaptive extends CardImpl { public WolfbittenCaptive(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WEREWOLF); @@ -32,7 +31,7 @@ public final class WolfbittenCaptive extends CardImpl { this.toughness = new MageInt(1); this.transformable = true; - this.secondSideCardClazz = KrallenhordeKiller.class; + this.secondSideCardClazz = mage.cards.k.KrallenhordeKiller.class; // {1}{G}: Wolfbitten Captive gets +2/+2 until end of turn. Activate this ability only once each turn. this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl("{1}{G}"))); diff --git a/Mage.Sets/src/mage/sets/Anthologies.java b/Mage.Sets/src/mage/sets/Anthologies.java index 02d7f59605..17df9798d6 100644 --- a/Mage.Sets/src/mage/sets/Anthologies.java +++ b/Mage.Sets/src/mage/sets/Anthologies.java @@ -19,7 +19,7 @@ public final class Anthologies extends ExpansionSet { private Anthologies() { super("Anthologies", "ATH", ExpansionSet.buildDate(1998, 11, 01), SetType.SUPPLEMENTAL); this.hasBoosters = false; - this.hasBasicLands = false; + this.hasBasicLands = true; cards.add(new SetCardInfo("Aesthir Glider", 67, Rarity.COMMON, mage.cards.a.AesthirGlider.class)); cards.add(new SetCardInfo("Armageddon", 1, Rarity.RARE, mage.cards.a.Armageddon.class)); diff --git a/Mage.Sets/src/mage/sets/ArabianNights.java b/Mage.Sets/src/mage/sets/ArabianNights.java index ecca8e9ec7..05f01c9e54 100644 --- a/Mage.Sets/src/mage/sets/ArabianNights.java +++ b/Mage.Sets/src/mage/sets/ArabianNights.java @@ -2,13 +2,6 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.a.ArmyOfAllah; -import mage.cards.f.FishliverOil; -import mage.cards.n.NafsAsp; -import mage.cards.o.Oubliette; -import mage.cards.p.Piety; -import mage.cards.r.RukhEgg; -import mage.cards.s.StoneThrowingDevils; import mage.constants.Rarity; import mage.constants.SetType; @@ -39,8 +32,8 @@ public final class ArabianNights extends ExpansionSet { cards.add(new SetCardInfo("Aladdin's Ring", 57, Rarity.RARE, mage.cards.a.AladdinsRing.class)); cards.add(new SetCardInfo("Ali Baba", 35, Rarity.UNCOMMON, mage.cards.a.AliBaba.class)); cards.add(new SetCardInfo("Ali from Cairo", 36, Rarity.RARE, mage.cards.a.AliFromCairo.class)); - cards.add(new SetCardInfo("Army of Allah", "2a", Rarity.COMMON, ArmyOfAllah.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Army of Allah", "2b", Rarity.COMMON, ArmyOfAllah.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Army of Allah", "2a", Rarity.COMMON, mage.cards.a.ArmyOfAllah.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Army of Allah", "2b", Rarity.COMMON, mage.cards.a.ArmyOfAllah.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bazaar of Baghdad", 70, Rarity.UNCOMMON, mage.cards.b.BazaarOfBaghdad.class)); cards.add(new SetCardInfo("Bird Maiden", "37a", Rarity.COMMON, mage.cards.b.BirdMaiden.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bird Maiden", "37b", Rarity.COMMON, mage.cards.b.BirdMaiden.class, NON_FULL_USE_VARIOUS)); @@ -65,8 +58,8 @@ public final class ArabianNights extends ExpansionSet { cards.add(new SetCardInfo("Erg Raiders", "25b", Rarity.COMMON, mage.cards.e.ErgRaiders.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Erhnam Djinn", 48, Rarity.RARE, mage.cards.e.ErhnamDjinn.class)); cards.add(new SetCardInfo("Eye for an Eye", 4, Rarity.UNCOMMON, mage.cards.e.EyeForAnEye.class)); - cards.add(new SetCardInfo("Fishliver Oil", "13a", Rarity.COMMON, FishliverOil.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Fishliver Oil", "13b", Rarity.COMMON, FishliverOil.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fishliver Oil", "13a", Rarity.COMMON, mage.cards.f.FishliverOil.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fishliver Oil", "13b", Rarity.COMMON, mage.cards.f.FishliverOil.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Flying Carpet", 63, Rarity.UNCOMMON, mage.cards.f.FlyingCarpet.class)); cards.add(new SetCardInfo("Flying Men", 14, Rarity.COMMON, mage.cards.f.FlyingMen.class)); cards.add(new SetCardInfo("Ghazban Ogre", 49, Rarity.COMMON, mage.cards.g.GhazbanOgre.class)); @@ -95,19 +88,19 @@ public final class ArabianNights extends ExpansionSet { cards.add(new SetCardInfo("Moorish Cavalry", "7a", Rarity.COMMON, mage.cards.m.MoorishCavalry.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Moorish Cavalry", "7b", Rarity.COMMON, mage.cards.m.MoorishCavalry.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 77, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Nafs Asp", "52a", Rarity.COMMON, NafsAsp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Nafs Asp", "52b", Rarity.COMMON, NafsAsp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Nafs Asp", "52a", Rarity.COMMON, mage.cards.n.NafsAsp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Nafs Asp", "52b", Rarity.COMMON, mage.cards.n.NafsAsp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Oasis", 78, Rarity.UNCOMMON, mage.cards.o.Oasis.class)); cards.add(new SetCardInfo("Old Man of the Sea", 18, Rarity.RARE, mage.cards.o.OldManOfTheSea.class)); - cards.add(new SetCardInfo("Oubliette", "31a", Rarity.COMMON, Oubliette.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Oubliette", "31b", Rarity.COMMON, Oubliette.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Piety", "8a", Rarity.COMMON, Piety.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Piety", "8b", Rarity.COMMON, Piety.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Oubliette", "31a", Rarity.COMMON, mage.cards.o.Oubliette.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Oubliette", "31b", Rarity.COMMON, mage.cards.o.Oubliette.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Piety", "8a", Rarity.COMMON, mage.cards.p.Piety.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Piety", "8b", Rarity.COMMON, mage.cards.p.Piety.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Pyramids", 67, Rarity.RARE, mage.cards.p.Pyramids.class)); cards.add(new SetCardInfo("Repentant Blacksmith", 9, Rarity.RARE, mage.cards.r.RepentantBlacksmith.class)); cards.add(new SetCardInfo("Ring of Ma'ruf", 68, Rarity.RARE, mage.cards.r.RingOfMaruf.class)); - cards.add(new SetCardInfo("Rukh Egg", "43a", Rarity.COMMON, RukhEgg.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Rukh Egg", "43b", Rarity.COMMON, RukhEgg.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rukh Egg", "43a", Rarity.COMMON, mage.cards.r.RukhEgg.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rukh Egg", "43b", Rarity.COMMON, mage.cards.r.RukhEgg.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sandals of Abdallah", 69, Rarity.UNCOMMON, mage.cards.s.SandalsOfAbdallah.class)); cards.add(new SetCardInfo("Sandstorm", 53, Rarity.COMMON, mage.cards.s.Sandstorm.class)); cards.add(new SetCardInfo("Serendib Djinn", 19, Rarity.RARE, mage.cards.s.SerendibDjinn.class)); @@ -115,8 +108,8 @@ public final class ArabianNights extends ExpansionSet { cards.add(new SetCardInfo("Sindbad", 21, Rarity.UNCOMMON, mage.cards.s.Sindbad.class)); cards.add(new SetCardInfo("Singing Tree", 54, Rarity.RARE, mage.cards.s.SingingTree.class)); cards.add(new SetCardInfo("Sorceress Queen", 32, Rarity.UNCOMMON, mage.cards.s.SorceressQueen.class)); - cards.add(new SetCardInfo("Stone-Throwing Devils", "33a", Rarity.COMMON, StoneThrowingDevils.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Stone-Throwing Devils", "33b", Rarity.COMMON, StoneThrowingDevils.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Stone-Throwing Devils", "33a", Rarity.COMMON, mage.cards.s.StoneThrowingDevils.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Stone-Throwing Devils", "33b", Rarity.COMMON, mage.cards.s.StoneThrowingDevils.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Unstable Mutation", 22, Rarity.COMMON, mage.cards.u.UnstableMutation.class)); cards.add(new SetCardInfo("War Elephant", "11a", Rarity.COMMON, mage.cards.w.WarElephant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("War Elephant", "11b", Rarity.COMMON, mage.cards.w.WarElephant.class, NON_FULL_USE_VARIOUS)); @@ -124,4 +117,4 @@ public final class ArabianNights extends ExpansionSet { cards.add(new SetCardInfo("Wyluli Wolf", "55b", Rarity.COMMON, mage.cards.w.WyluliWolf.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ydwen Efreet", 44, Rarity.RARE, mage.cards.y.YdwenEfreet.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/ChampionsOfKamigawa.java b/Mage.Sets/src/mage/sets/ChampionsOfKamigawa.java index 7a61cbb5da..c941893a4d 100644 --- a/Mage.Sets/src/mage/sets/ChampionsOfKamigawa.java +++ b/Mage.Sets/src/mage/sets/ChampionsOfKamigawa.java @@ -1,7 +1,6 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.b.BrothersYamazaki; import mage.constants.Rarity; import mage.constants.SetType; @@ -22,6 +21,7 @@ public final class ChampionsOfKamigawa extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Akki Avalanchers", 151, Rarity.COMMON, mage.cards.a.AkkiAvalanchers.class)); cards.add(new SetCardInfo("Akki Coalflinger", 152, Rarity.UNCOMMON, mage.cards.a.AkkiCoalflinger.class)); cards.add(new SetCardInfo("Akki Lavarunner", 153, Rarity.RARE, mage.cards.a.AkkiLavarunner.class)); @@ -40,15 +40,15 @@ public final class ChampionsOfKamigawa extends ExpansionSet { cards.add(new SetCardInfo("Blood Speaker", 103, Rarity.UNCOMMON, mage.cards.b.BloodSpeaker.class)); cards.add(new SetCardInfo("Bloodthirsty Ogre", 104, Rarity.UNCOMMON, mage.cards.b.BloodthirstyOgre.class)); cards.add(new SetCardInfo("Boseiju, Who Shelters All", 273, Rarity.RARE, mage.cards.b.BoseijuWhoSheltersAll.class)); - cards.add(new SetCardInfo("Brothers Yamazaki", "160a", Rarity.UNCOMMON, BrothersYamazaki.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Brothers Yamazaki", "160b", Rarity.UNCOMMON, BrothersYamazaki.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Brothers Yamazaki", "160a", Rarity.UNCOMMON, mage.cards.b.BrothersYamazaki.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Brothers Yamazaki", "160b", Rarity.UNCOMMON, mage.cards.b.BrothersYamazaki.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Brutal Deceiver", 161, Rarity.COMMON, mage.cards.b.BrutalDeceiver.class)); cards.add(new SetCardInfo("Budoka Gardener", 202, Rarity.RARE, mage.cards.b.BudokaGardener.class)); cards.add(new SetCardInfo("Burr Grafter", 203, Rarity.COMMON, mage.cards.b.BurrGrafter.class)); cards.add(new SetCardInfo("Bushi Tenderfoot", 2, Rarity.UNCOMMON, mage.cards.b.BushiTenderfoot.class)); cards.add(new SetCardInfo("Cage of Hands", 3, Rarity.COMMON, mage.cards.c.CageOfHands.class)); - cards.add(new SetCardInfo("Callous Deceiver", 53, Rarity.COMMON, mage.cards.c.CallousDeceiver.class)); cards.add(new SetCardInfo("Call to Glory", 4, Rarity.COMMON, mage.cards.c.CallToGlory.class)); + cards.add(new SetCardInfo("Callous Deceiver", 53, Rarity.COMMON, mage.cards.c.CallousDeceiver.class)); cards.add(new SetCardInfo("Candles' Glow", 5, Rarity.UNCOMMON, mage.cards.c.CandlesGlow.class)); cards.add(new SetCardInfo("Cleanfall", 6, Rarity.UNCOMMON, mage.cards.c.Cleanfall.class)); cards.add(new SetCardInfo("Cloudcrest Lake", 274, Rarity.UNCOMMON, mage.cards.c.CloudcrestLake.class)); @@ -100,19 +100,19 @@ public final class ChampionsOfKamigawa extends ExpansionSet { cards.add(new SetCardInfo("Gutwrencher Oni", 113, Rarity.UNCOMMON, mage.cards.g.GutwrencherOni.class)); cards.add(new SetCardInfo("Hair-Strung Koto", 252, Rarity.RARE, mage.cards.h.HairStrungKoto.class)); cards.add(new SetCardInfo("Hall of the Bandit Lord", 277, Rarity.RARE, mage.cards.h.HallOfTheBanditLord.class)); - cards.add(new SetCardInfo("Hanabi Blast", 170, Rarity.UNCOMMON, mage.cards.h.HanabiBlast.class)); cards.add(new SetCardInfo("Hana Kami", 211, Rarity.UNCOMMON, mage.cards.h.HanaKami.class)); + cards.add(new SetCardInfo("Hanabi Blast", 170, Rarity.UNCOMMON, mage.cards.h.HanabiBlast.class)); cards.add(new SetCardInfo("Hankyu", 253, Rarity.UNCOMMON, mage.cards.h.Hankyu.class)); cards.add(new SetCardInfo("Harsh Deceiver", 11, Rarity.COMMON, mage.cards.h.HarshDeceiver.class)); + cards.add(new SetCardInfo("He Who Hungers", 114, Rarity.RARE, mage.cards.h.HeWhoHungers.class)); cards.add(new SetCardInfo("Heartbeat of Spring", 212, Rarity.RARE, mage.cards.h.HeartbeatOfSpring.class)); cards.add(new SetCardInfo("Hearth Kami", 171, Rarity.COMMON, mage.cards.h.HearthKami.class)); - cards.add(new SetCardInfo("He Who Hungers", 114, Rarity.RARE, mage.cards.h.HeWhoHungers.class)); cards.add(new SetCardInfo("Hideous Laughter", 115, Rarity.UNCOMMON, mage.cards.h.HideousLaughter.class)); cards.add(new SetCardInfo("Hikari, Twilight Guardian", 12, Rarity.RARE, mage.cards.h.HikariTwilightGuardian.class)); cards.add(new SetCardInfo("Hinder", 65, Rarity.UNCOMMON, mage.cards.h.Hinder.class)); - cards.add(new SetCardInfo("Hisoka, Minamo Sensei", 66, Rarity.RARE, mage.cards.h.HisokaMinamoSensei.class)); cards.add(new SetCardInfo("Hisoka's Defiance", 67, Rarity.COMMON, mage.cards.h.HisokasDefiance.class)); cards.add(new SetCardInfo("Hisoka's Guard", 68, Rarity.COMMON, mage.cards.h.HisokasGuard.class)); + cards.add(new SetCardInfo("Hisoka, Minamo Sensei", 66, Rarity.RARE, mage.cards.h.HisokaMinamoSensei.class)); cards.add(new SetCardInfo("Hold the Line", 13, Rarity.RARE, mage.cards.h.HoldTheLine.class)); cards.add(new SetCardInfo("Honden of Cleansing Fire", 14, Rarity.UNCOMMON, mage.cards.h.HondenOfCleansingFire.class)); cards.add(new SetCardInfo("Honden of Infinite Rage", 172, Rarity.UNCOMMON, mage.cards.h.HondenOfInfiniteRage.class)); @@ -130,7 +130,7 @@ public final class ChampionsOfKamigawa extends ExpansionSet { cards.add(new SetCardInfo("Indomitable Will", 17, Rarity.COMMON, mage.cards.i.IndomitableWill.class)); cards.add(new SetCardInfo("Initiate of Blood", 173, Rarity.UNCOMMON, mage.cards.i.InitiateOfBlood.class)); cards.add(new SetCardInfo("Innocence Kami", 18, Rarity.UNCOMMON, mage.cards.i.InnocenceKami.class)); - cards.add(new SetCardInfo("Isamaru, Hound of Konda", 19, Rarity.RARE, mage.cards.i.IsamaruHoundofKonda.class)); + cards.add(new SetCardInfo("Isamaru, Hound of Konda", 19, Rarity.RARE, mage.cards.i.IsamaruHoundOfKonda.class)); cards.add(new SetCardInfo("Island", 291, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 292, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 293, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); @@ -167,11 +167,11 @@ public final class ChampionsOfKamigawa extends ExpansionSet { cards.add(new SetCardInfo("Kodama's Might", 224, Rarity.COMMON, mage.cards.k.KodamasMight.class)); cards.add(new SetCardInfo("Kodama's Reach", 225, Rarity.COMMON, mage.cards.k.KodamasReach.class)); cards.add(new SetCardInfo("Kokusho, the Evening Star", 122, Rarity.RARE, mage.cards.k.KokushoTheEveningStar.class)); - cards.add(new SetCardInfo("Konda, Lord of Eiganjo", 30, Rarity.RARE, mage.cards.k.KondaLordOfEiganjo.class)); cards.add(new SetCardInfo("Konda's Banner", 259, Rarity.RARE, mage.cards.k.KondasBanner.class)); cards.add(new SetCardInfo("Konda's Hatamoto", 31, Rarity.UNCOMMON, mage.cards.k.KondasHatamoto.class)); - cards.add(new SetCardInfo("Kumano, Master Yamabushi", 176, Rarity.RARE, mage.cards.k.KumanoMasterYamabushi.class)); + cards.add(new SetCardInfo("Konda, Lord of Eiganjo", 30, Rarity.RARE, mage.cards.k.KondaLordOfEiganjo.class)); cards.add(new SetCardInfo("Kumano's Pupils", 177, Rarity.UNCOMMON, mage.cards.k.KumanosPupils.class)); + cards.add(new SetCardInfo("Kumano, Master Yamabushi", 176, Rarity.RARE, mage.cards.k.KumanoMasterYamabushi.class)); cards.add(new SetCardInfo("Kuro, Pitlord", 123, Rarity.RARE, mage.cards.k.KuroPitlord.class)); cards.add(new SetCardInfo("Kusari-Gama", 260, Rarity.RARE, mage.cards.k.KusariGama.class)); cards.add(new SetCardInfo("Lantern Kami", 32, Rarity.COMMON, mage.cards.l.LanternKami.class)); @@ -280,9 +280,9 @@ public final class ChampionsOfKamigawa extends ExpansionSet { cards.add(new SetCardInfo("Soratami Savant", 90, Rarity.UNCOMMON, mage.cards.s.SoratamiSavant.class)); cards.add(new SetCardInfo("Soratami Seer", 91, Rarity.UNCOMMON, mage.cards.s.SoratamiSeer.class)); cards.add(new SetCardInfo("Sosuke, Son of Seshiro", 244, Rarity.UNCOMMON, mage.cards.s.SosukeSonOfSeshiro.class)); + cards.add(new SetCardInfo("Soul of Magma", 189, Rarity.COMMON, mage.cards.s.SoulOfMagma.class)); cards.add(new SetCardInfo("Soulblast", 190, Rarity.RARE, mage.cards.s.Soulblast.class)); cards.add(new SetCardInfo("Soulless Revival", 144, Rarity.COMMON, mage.cards.s.SoullessRevival.class)); - cards.add(new SetCardInfo("Soul of Magma", 189, Rarity.COMMON, mage.cards.s.SoulOfMagma.class)); cards.add(new SetCardInfo("Squelch", 92, Rarity.UNCOMMON, mage.cards.s.Squelch.class)); cards.add(new SetCardInfo("Stone Rain", 191, Rarity.COMMON, mage.cards.s.StoneRain.class)); cards.add(new SetCardInfo("Strange Inversion", 192, Rarity.UNCOMMON, mage.cards.s.StrangeInversion.class)); @@ -302,7 +302,7 @@ public final class ChampionsOfKamigawa extends ExpansionSet { cards.add(new SetCardInfo("The Unspeakable", 98, Rarity.RARE, mage.cards.t.TheUnspeakable.class)); cards.add(new SetCardInfo("Thief of Hope", 147, Rarity.UNCOMMON, mage.cards.t.ThiefOfHope.class)); cards.add(new SetCardInfo("Thoughtbind", 96, Rarity.COMMON, mage.cards.t.Thoughtbind.class)); - cards.add(new SetCardInfo("Thousand-legged Kami", 246, Rarity.UNCOMMON, mage.cards.t.ThousandleggedKami.class)); + cards.add(new SetCardInfo("Thousand-legged Kami", 246, Rarity.UNCOMMON, mage.cards.t.ThousandLeggedKami.class)); cards.add(new SetCardInfo("Through the Breach", 193, Rarity.RARE, mage.cards.t.ThroughTheBreach.class)); cards.add(new SetCardInfo("Tide of War", 194, Rarity.RARE, mage.cards.t.TideOfWar.class)); cards.add(new SetCardInfo("Time of Need", 247, Rarity.UNCOMMON, mage.cards.t.TimeOfNeed.class)); @@ -329,5 +329,4 @@ public final class ChampionsOfKamigawa extends ExpansionSet { cards.add(new SetCardInfo("Yosei, the Morning Star", 50, Rarity.RARE, mage.cards.y.YoseiTheMorningStar.class)); cards.add(new SetCardInfo("Zo-Zu the Punisher", 200, Rarity.RARE, mage.cards.z.ZoZuThePunisher.class)); } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/ClassicSixthEdition.java b/Mage.Sets/src/mage/sets/ClassicSixthEdition.java index b7309d9c26..0494b40b09 100644 --- a/Mage.Sets/src/mage/sets/ClassicSixthEdition.java +++ b/Mage.Sets/src/mage/sets/ClassicSixthEdition.java @@ -2,16 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.d.DrySpell; -import mage.cards.f.FeastOfTheUnicorn; -import mage.cards.m.MesaFalcon; -import mage.cards.s.SoldeviSage; -import mage.cards.v.VodalianSoldiers; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class ClassicSixthEdition extends ExpansionSet { @@ -30,6 +24,7 @@ public final class ClassicSixthEdition extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abduction", 55, Rarity.UNCOMMON, mage.cards.a.Abduction.class)); cards.add(new SetCardInfo("Abyssal Hunter", 109, Rarity.RARE, mage.cards.a.AbyssalHunter.class)); cards.add(new SetCardInfo("Abyssal Specter", 110, Rarity.UNCOMMON, mage.cards.a.AbyssalSpecter.class)); @@ -106,7 +101,7 @@ public final class ClassicSixthEdition extends ExpansionSet { cards.add(new SetCardInfo("Dread of Night", 122, Rarity.UNCOMMON, mage.cards.d.DreadOfNight.class)); cards.add(new SetCardInfo("Dream Cache", 66, Rarity.COMMON, mage.cards.d.DreamCache.class)); cards.add(new SetCardInfo("Drudge Skeletons", 123, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class)); - cards.add(new SetCardInfo("Dry Spell", 124, Rarity.COMMON, DrySpell.class)); + cards.add(new SetCardInfo("Dry Spell", 124, Rarity.COMMON, mage.cards.d.DrySpell.class)); cards.add(new SetCardInfo("Dwarven Ruins", 323, Rarity.UNCOMMON, mage.cards.d.DwarvenRuins.class)); cards.add(new SetCardInfo("Early Harvest", 222, Rarity.RARE, mage.cards.e.EarlyHarvest.class)); cards.add(new SetCardInfo("Earthquake", 173, Rarity.RARE, mage.cards.e.Earthquake.class)); @@ -126,7 +121,7 @@ public final class ClassicSixthEdition extends ExpansionSet { cards.add(new SetCardInfo("Familiar Ground", 228, Rarity.UNCOMMON, mage.cards.f.FamiliarGround.class)); cards.add(new SetCardInfo("Fatal Blow", 128, Rarity.COMMON, mage.cards.f.FatalBlow.class)); cards.add(new SetCardInfo("Fear", 129, Rarity.COMMON, mage.cards.f.Fear.class)); - cards.add(new SetCardInfo("Feast of the Unicorn", 130, Rarity.COMMON, FeastOfTheUnicorn.class)); + cards.add(new SetCardInfo("Feast of the Unicorn", 130, Rarity.COMMON, mage.cards.f.FeastOfTheUnicorn.class)); cards.add(new SetCardInfo("Femeref Archers", 229, Rarity.UNCOMMON, mage.cards.f.FemerefArchers.class)); cards.add(new SetCardInfo("Feral Shadow", 131, Rarity.COMMON, mage.cards.f.FeralShadow.class)); cards.add(new SetCardInfo("Fervor", 174, Rarity.RARE, mage.cards.f.Fervor.class)); @@ -223,7 +218,7 @@ public final class ClassicSixthEdition extends ExpansionSet { cards.add(new SetCardInfo("Meekstone", 299, Rarity.RARE, mage.cards.m.Meekstone.class)); cards.add(new SetCardInfo("Memory Lapse", 81, Rarity.COMMON, mage.cards.m.MemoryLapse.class)); cards.add(new SetCardInfo("Merfolk of the Pearl Trident", 82, Rarity.COMMON, mage.cards.m.MerfolkOfThePearlTrident.class)); - cards.add(new SetCardInfo("Mesa Falcon", 31, Rarity.COMMON, MesaFalcon.class)); + cards.add(new SetCardInfo("Mesa Falcon", 31, Rarity.COMMON, mage.cards.m.MesaFalcon.class)); cards.add(new SetCardInfo("Millstone", 300, Rarity.RARE, mage.cards.m.Millstone.class)); cards.add(new SetCardInfo("Mind Warp", 143, Rarity.UNCOMMON, mage.cards.m.MindWarp.class)); cards.add(new SetCardInfo("Mischievous Poltergeist", 144, Rarity.UNCOMMON, mage.cards.m.MischievousPoltergeist.class)); @@ -309,7 +304,7 @@ public final class ClassicSixthEdition extends ExpansionSet { cards.add(new SetCardInfo("Skull Catapult", 310, Rarity.UNCOMMON, mage.cards.s.SkullCatapult.class)); cards.add(new SetCardInfo("Sky Diamond", 311, Rarity.UNCOMMON, mage.cards.s.SkyDiamond.class)); cards.add(new SetCardInfo("Snake Basket", 312, Rarity.RARE, mage.cards.s.SnakeBasket.class)); - cards.add(new SetCardInfo("Soldevi Sage", 99, Rarity.UNCOMMON, SoldeviSage.class)); + cards.add(new SetCardInfo("Soldevi Sage", 99, Rarity.UNCOMMON, mage.cards.s.SoldeviSage.class)); cards.add(new SetCardInfo("Soul Net", 313, Rarity.UNCOMMON, mage.cards.s.SoulNet.class)); cards.add(new SetCardInfo("Spell Blast", 100, Rarity.COMMON, mage.cards.s.SpellBlast.class)); cards.add(new SetCardInfo("Spirit Link", 43, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class)); @@ -360,7 +355,7 @@ public final class ClassicSixthEdition extends ExpansionSet { cards.add(new SetCardInfo("Vertigo", 212, Rarity.UNCOMMON, mage.cards.v.Vertigo.class)); cards.add(new SetCardInfo("Viashino Warrior", 213, Rarity.COMMON, mage.cards.v.ViashinoWarrior.class)); cards.add(new SetCardInfo("Vitalize", 265, Rarity.COMMON, mage.cards.v.Vitalize.class)); - cards.add(new SetCardInfo("Vodalian Soldiers", 104, Rarity.COMMON, VodalianSoldiers.class)); + cards.add(new SetCardInfo("Vodalian Soldiers", 104, Rarity.COMMON, mage.cards.v.VodalianSoldiers.class)); cards.add(new SetCardInfo("Volcanic Dragon", 214, Rarity.RARE, mage.cards.v.VolcanicDragon.class)); cards.add(new SetCardInfo("Volcanic Geyser", 215, Rarity.UNCOMMON, mage.cards.v.VolcanicGeyser.class)); cards.add(new SetCardInfo("Waiting in the Weeds", 266, Rarity.RARE, mage.cards.w.WaitingInTheWeeds.class)); @@ -381,4 +376,4 @@ public final class ClassicSixthEdition extends ExpansionSet { cards.add(new SetCardInfo("Zombie Master", 162, Rarity.RARE, mage.cards.z.ZombieMaster.class)); cards.add(new SetCardInfo("Zur's Weirding", 108, Rarity.RARE, mage.cards.z.ZursWeirding.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Commander2013Edition.java b/Mage.Sets/src/mage/sets/Commander2013Edition.java index 61f9d76730..e1011787db 100644 --- a/Mage.Sets/src/mage/sets/Commander2013Edition.java +++ b/Mage.Sets/src/mage/sets/Commander2013Edition.java @@ -2,12 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.n.NightSoil; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author LevelX2 */ public final class Commander2013Edition extends ExpansionSet { @@ -21,6 +19,7 @@ public final class Commander2013Edition extends ExpansionSet { private Commander2013Edition() { super("Commander 2013 Edition", "C13", ExpansionSet.buildDate(2013, 11, 01), SetType.SUPPLEMENTAL); this.blockName = "Command Zone"; + cards.add(new SetCardInfo("Acidic Slime", 134, Rarity.UNCOMMON, mage.cards.a.AcidicSlime.class)); cards.add(new SetCardInfo("Act of Authority", 1, Rarity.RARE, mage.cards.a.ActOfAuthority.class)); cards.add(new SetCardInfo("Aerie Mystics", 2, Rarity.UNCOMMON, mage.cards.a.AerieMystics.class)); @@ -214,7 +213,7 @@ public final class Commander2013Edition extends ExpansionSet { cards.add(new SetCardInfo("Nevinyrral's Disk", 248, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); cards.add(new SetCardInfo("New Benalia", 309, Rarity.UNCOMMON, mage.cards.n.NewBenalia.class)); cards.add(new SetCardInfo("Nightscape Familiar", 83, Rarity.COMMON, mage.cards.n.NightscapeFamiliar.class)); - cards.add(new SetCardInfo("Night Soil", 158, Rarity.COMMON, NightSoil.class)); + cards.add(new SetCardInfo("Night Soil", 158, Rarity.COMMON, mage.cards.n.NightSoil.class)); cards.add(new SetCardInfo("Nihil Spellbomb", 249, Rarity.COMMON, mage.cards.n.NihilSpellbomb.class)); cards.add(new SetCardInfo("Nivix Guildmage", 202, Rarity.UNCOMMON, mage.cards.n.NivixGuildmage.class)); cards.add(new SetCardInfo("Obelisk of Esper", 250, Rarity.COMMON, mage.cards.o.ObeliskOfEsper.class)); @@ -379,4 +378,4 @@ public final class Commander2013Edition extends ExpansionSet { cards.add(new SetCardInfo("Wrath of God", 27, Rarity.RARE, mage.cards.w.WrathOfGod.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java b/Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java index 0bc7d7758f..493602f349 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java +++ b/Mage.Sets/src/mage/sets/DuelDecksElspethVsKiora.java @@ -2,7 +2,6 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.i.IcatianJavelineers; import mage.constants.Rarity; import mage.constants.SetType; @@ -45,7 +44,7 @@ public final class DuelDecksElspethVsKiora extends ExpansionSet { cards.add(new SetCardInfo("Gustcloak Savior", 11, Rarity.RARE, mage.cards.g.GustcloakSavior.class)); cards.add(new SetCardInfo("Gustcloak Sentinel", 12, Rarity.UNCOMMON, mage.cards.g.GustcloakSentinel.class)); cards.add(new SetCardInfo("Gustcloak Skirmisher", 13, Rarity.UNCOMMON, mage.cards.g.GustcloakSkirmisher.class)); - cards.add(new SetCardInfo("Icatian Javelineers", 14, Rarity.COMMON, IcatianJavelineers.class)); + cards.add(new SetCardInfo("Icatian Javelineers", 14, Rarity.COMMON, mage.cards.i.IcatianJavelineers.class)); cards.add(new SetCardInfo("Inkwell Leviathan", 37, Rarity.RARE, mage.cards.i.InkwellLeviathan.class)); cards.add(new SetCardInfo("Island", 60, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 61, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/EternalMasters.java b/Mage.Sets/src/mage/sets/EternalMasters.java index 87051cc69d..a6c0a96d5c 100644 --- a/Mage.Sets/src/mage/sets/EternalMasters.java +++ b/Mage.Sets/src/mage/sets/EternalMasters.java @@ -2,12 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.h.HymnToTourach; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class EternalMasters extends ExpansionSet { @@ -28,6 +26,7 @@ public final class EternalMasters extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Abundant Growth", 156, Rarity.COMMON, mage.cards.a.AbundantGrowth.class)); cards.add(new SetCardInfo("Ancestral Mask", 157, Rarity.UNCOMMON, mage.cards.a.AncestralMask.class)); cards.add(new SetCardInfo("Animate Dead", 78, Rarity.UNCOMMON, mage.cards.a.AnimateDead.class)); @@ -128,7 +127,7 @@ public final class EternalMasters extends ExpansionSet { cards.add(new SetCardInfo("Honden of Seeing Winds", 54, Rarity.UNCOMMON, mage.cards.h.HondenOfSeeingWinds.class)); cards.add(new SetCardInfo("Humble", 14, Rarity.COMMON, mage.cards.h.Humble.class)); cards.add(new SetCardInfo("Hydroblast", 55, Rarity.UNCOMMON, mage.cards.h.Hydroblast.class)); - cards.add(new SetCardInfo("Hymn to Tourach", 92, Rarity.UNCOMMON, HymnToTourach.class)); + cards.add(new SetCardInfo("Hymn to Tourach", 92, Rarity.UNCOMMON, mage.cards.h.HymnToTourach.class)); cards.add(new SetCardInfo("Ichorid", 93, Rarity.RARE, mage.cards.i.Ichorid.class)); cards.add(new SetCardInfo("Imperious Perfect", 173, Rarity.RARE, mage.cards.i.ImperiousPerfect.class)); cards.add(new SetCardInfo("Inkwell Leviathan", 56, Rarity.RARE, mage.cards.i.InkwellLeviathan.class)); @@ -278,5 +277,4 @@ public final class EternalMasters extends ExpansionSet { cards.add(new SetCardInfo("Young Pyromancer", 155, Rarity.UNCOMMON, mage.cards.y.YoungPyromancer.class)); cards.add(new SetCardInfo("Zealous Persecution", 213, Rarity.UNCOMMON, mage.cards.z.ZealousPersecution.class)); } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/FallenEmpires.java b/Mage.Sets/src/mage/sets/FallenEmpires.java index 7f31d69080..d8dcd103eb 100644 --- a/Mage.Sets/src/mage/sets/FallenEmpires.java +++ b/Mage.Sets/src/mage/sets/FallenEmpires.java @@ -2,42 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.a.ArmorThrull; -import mage.cards.b.BasalThrull; -import mage.cards.b.BrassclawOrcs; -import mage.cards.c.CombatMedic; -import mage.cards.d.DwarvenSoldier; -import mage.cards.e.ElvenFortress; -import mage.cards.e.ElvishHunter; -import mage.cards.e.ElvishScout; -import mage.cards.f.FarrelsZealot; -import mage.cards.g.GoblinChirurgeon; -import mage.cards.g.GoblinGrenade; -import mage.cards.g.GoblinWarDrums; -import mage.cards.h.HighTide; -import mage.cards.h.Homarid; -import mage.cards.h.HomaridWarrior; -import mage.cards.h.HymnToTourach; -import mage.cards.i.IcatianInfantry; -import mage.cards.i.IcatianJavelineers; -import mage.cards.i.IcatianMoneychanger; -import mage.cards.i.IcatianScout; -import mage.cards.i.InitiatesOfTheEbonHand; -import mage.cards.m.MindstabThrull; -import mage.cards.n.Necrite; -import mage.cards.n.NightSoil; -import mage.cards.o.OrcishSpy; -import mage.cards.o.OrcishVeteran; -import mage.cards.o.OrderOfLeitbur; -import mage.cards.o.OrderOfTheEbonHand; -import mage.cards.t.ThornThallid; -import mage.cards.v.VodalianMage; -import mage.cards.v.VodalianSoldiers; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class FallenEmpires extends ExpansionSet { @@ -57,26 +25,27 @@ public final class FallenEmpires extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Aeolipile", 81, Rarity.RARE, mage.cards.a.Aeolipile.class)); - cards.add(new SetCardInfo("Armor Thrull", "33a", Rarity.COMMON, ArmorThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Armor Thrull", "33b", Rarity.COMMON, ArmorThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Armor Thrull", "33c", Rarity.COMMON, ArmorThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Armor Thrull", "33d", Rarity.COMMON, ArmorThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Armor Thrull", "33a", Rarity.COMMON, mage.cards.a.ArmorThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Armor Thrull", "33b", Rarity.COMMON, mage.cards.a.ArmorThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Armor Thrull", "33c", Rarity.COMMON, mage.cards.a.ArmorThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Armor Thrull", "33d", Rarity.COMMON, mage.cards.a.ArmorThrull.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Balm of Restoration", 82, Rarity.RARE, mage.cards.b.BalmOfRestoration.class)); - cards.add(new SetCardInfo("Basal Thrull", "34a", Rarity.COMMON, BasalThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Basal Thrull", "34b", Rarity.COMMON, BasalThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Basal Thrull", "34c", Rarity.COMMON, BasalThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Basal Thrull", "34d", Rarity.COMMON, BasalThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Basal Thrull", "34a", Rarity.COMMON, mage.cards.b.BasalThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Basal Thrull", "34b", Rarity.COMMON, mage.cards.b.BasalThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Basal Thrull", "34c", Rarity.COMMON, mage.cards.b.BasalThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Basal Thrull", "34d", Rarity.COMMON, mage.cards.b.BasalThrull.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bottomless Vault", 92, Rarity.RARE, mage.cards.b.BottomlessVault.class)); - cards.add(new SetCardInfo("Brassclaw Orcs", "49a", Rarity.COMMON, BrassclawOrcs.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Brassclaw Orcs", "49b", Rarity.COMMON, BrassclawOrcs.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Brassclaw Orcs", "49c", Rarity.COMMON, BrassclawOrcs.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Brassclaw Orcs", "49d", Rarity.COMMON, BrassclawOrcs.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Brassclaw Orcs", "49a", Rarity.COMMON, mage.cards.b.BrassclawOrcs.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Brassclaw Orcs", "49b", Rarity.COMMON, mage.cards.b.BrassclawOrcs.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Brassclaw Orcs", "49c", Rarity.COMMON, mage.cards.b.BrassclawOrcs.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Brassclaw Orcs", "49d", Rarity.COMMON, mage.cards.b.BrassclawOrcs.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Breeding Pit", 35, Rarity.UNCOMMON, mage.cards.b.BreedingPit.class)); - cards.add(new SetCardInfo("Combat Medic", "1a", Rarity.COMMON, CombatMedic.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Combat Medic", "1b", Rarity.COMMON, CombatMedic.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Combat Medic", "1c", Rarity.COMMON, CombatMedic.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Combat Medic", "1d", Rarity.COMMON, CombatMedic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Combat Medic", "1a", Rarity.COMMON, mage.cards.c.CombatMedic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Combat Medic", "1b", Rarity.COMMON, mage.cards.c.CombatMedic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Combat Medic", "1c", Rarity.COMMON, mage.cards.c.CombatMedic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Combat Medic", "1d", Rarity.COMMON, mage.cards.c.CombatMedic.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Conch Horn", 83, Rarity.RARE, mage.cards.c.ConchHorn.class)); cards.add(new SetCardInfo("Deep Spawn", 17, Rarity.UNCOMMON, mage.cards.d.DeepSpawn.class)); cards.add(new SetCardInfo("Delif's Cone", 84, Rarity.COMMON, mage.cards.d.DelifsCone.class)); @@ -88,114 +57,114 @@ public final class FallenEmpires extends ExpansionSet { cards.add(new SetCardInfo("Dwarven Hold", 93, Rarity.RARE, mage.cards.d.DwarvenHold.class)); cards.add(new SetCardInfo("Dwarven Lieutenant", 52, Rarity.UNCOMMON, mage.cards.d.DwarvenLieutenant.class)); cards.add(new SetCardInfo("Dwarven Ruins", 94, Rarity.UNCOMMON, mage.cards.d.DwarvenRuins.class)); - cards.add(new SetCardInfo("Dwarven Soldier", "53a", Rarity.COMMON, DwarvenSoldier.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dwarven Soldier", "53b", Rarity.COMMON, DwarvenSoldier.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dwarven Soldier", "53c", Rarity.COMMON, DwarvenSoldier.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dwarven Soldier", "53a", Rarity.COMMON, mage.cards.d.DwarvenSoldier.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dwarven Soldier", "53b", Rarity.COMMON, mage.cards.d.DwarvenSoldier.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dwarven Soldier", "53c", Rarity.COMMON, mage.cards.d.DwarvenSoldier.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ebon Praetor", 37, Rarity.RARE, mage.cards.e.EbonPraetor.class)); cards.add(new SetCardInfo("Ebon Stronghold", 95, Rarity.UNCOMMON, mage.cards.e.EbonStronghold.class)); - cards.add(new SetCardInfo("Elven Fortress", "65a", Rarity.COMMON, ElvenFortress.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elven Fortress", "65b", Rarity.COMMON, ElvenFortress.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elven Fortress", "65c", Rarity.COMMON, ElvenFortress.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elven Fortress", "65d", Rarity.COMMON, ElvenFortress.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elven Fortress", "65a", Rarity.COMMON, mage.cards.e.ElvenFortress.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elven Fortress", "65b", Rarity.COMMON, mage.cards.e.ElvenFortress.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elven Fortress", "65c", Rarity.COMMON, mage.cards.e.ElvenFortress.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elven Fortress", "65d", Rarity.COMMON, mage.cards.e.ElvenFortress.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Elven Lyre", 87, Rarity.RARE, mage.cards.e.ElvenLyre.class)); cards.add(new SetCardInfo("Elvish Farmer", 66, Rarity.RARE, mage.cards.e.ElvishFarmer.class)); - cards.add(new SetCardInfo("Elvish Hunter", "67a", Rarity.COMMON, ElvishHunter.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elvish Hunter", "67b", Rarity.COMMON, ElvishHunter.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elvish Hunter", "67c", Rarity.COMMON, ElvishHunter.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elvish Scout", "68a", Rarity.COMMON, ElvishScout.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elvish Scout", "68b", Rarity.COMMON, ElvishScout.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elvish Scout", "68c", Rarity.COMMON, ElvishScout.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elvish Hunter", "67a", Rarity.COMMON, mage.cards.e.ElvishHunter.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elvish Hunter", "67b", Rarity.COMMON, mage.cards.e.ElvishHunter.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elvish Hunter", "67c", Rarity.COMMON, mage.cards.e.ElvishHunter.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elvish Scout", "68a", Rarity.COMMON, mage.cards.e.ElvishScout.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elvish Scout", "68b", Rarity.COMMON, mage.cards.e.ElvishScout.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elvish Scout", "68c", Rarity.COMMON, mage.cards.e.ElvishScout.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Farrel's Mantle", 2, Rarity.UNCOMMON, mage.cards.f.FarrelsMantle.class)); - cards.add(new SetCardInfo("Farrel's Zealot", "3a", Rarity.COMMON, FarrelsZealot.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Farrel's Zealot", "3b", Rarity.COMMON, FarrelsZealot.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Farrel's Zealot", "3c", Rarity.COMMON, FarrelsZealot.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Farrel's Zealot", "3a", Rarity.COMMON, mage.cards.f.FarrelsZealot.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Farrel's Zealot", "3b", Rarity.COMMON, mage.cards.f.FarrelsZealot.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Farrel's Zealot", "3c", Rarity.COMMON, mage.cards.f.FarrelsZealot.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Farrelite Priest", 4, Rarity.UNCOMMON, mage.cards.f.FarrelitePriest.class)); cards.add(new SetCardInfo("Feral Thallid", 69, Rarity.UNCOMMON, mage.cards.f.FeralThallid.class)); cards.add(new SetCardInfo("Fungal Bloom", 70, Rarity.RARE, mage.cards.f.FungalBloom.class)); - cards.add(new SetCardInfo("Goblin Chirurgeon", "54a", Rarity.COMMON, GoblinChirurgeon.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Goblin Chirurgeon", "54b", Rarity.COMMON, GoblinChirurgeon.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Goblin Chirurgeon", "54c", Rarity.COMMON, GoblinChirurgeon.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin Chirurgeon", "54a", Rarity.COMMON, mage.cards.g.GoblinChirurgeon.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin Chirurgeon", "54b", Rarity.COMMON, mage.cards.g.GoblinChirurgeon.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin Chirurgeon", "54c", Rarity.COMMON, mage.cards.g.GoblinChirurgeon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Goblin Flotilla", 55, Rarity.RARE, mage.cards.g.GoblinFlotilla.class)); - cards.add(new SetCardInfo("Goblin Grenade", "56a", Rarity.COMMON, GoblinGrenade.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Goblin Grenade", "56b", Rarity.COMMON, GoblinGrenade.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Goblin Grenade", "56c", Rarity.COMMON, GoblinGrenade.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin Grenade", "56a", Rarity.COMMON, mage.cards.g.GoblinGrenade.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin Grenade", "56b", Rarity.COMMON, mage.cards.g.GoblinGrenade.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin Grenade", "56c", Rarity.COMMON, mage.cards.g.GoblinGrenade.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Goblin Kites", 57, Rarity.UNCOMMON, mage.cards.g.GoblinKites.class)); - cards.add(new SetCardInfo("Goblin War Drums", "58a", Rarity.COMMON, GoblinWarDrums.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Goblin War Drums", "58b", Rarity.COMMON, GoblinWarDrums.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Goblin War Drums", "58c", Rarity.COMMON, GoblinWarDrums.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Goblin War Drums", "58d", Rarity.COMMON, GoblinWarDrums.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin War Drums", "58a", Rarity.COMMON, mage.cards.g.GoblinWarDrums.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin War Drums", "58b", Rarity.COMMON, mage.cards.g.GoblinWarDrums.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin War Drums", "58c", Rarity.COMMON, mage.cards.g.GoblinWarDrums.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goblin War Drums", "58d", Rarity.COMMON, mage.cards.g.GoblinWarDrums.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Goblin Warrens", 59, Rarity.RARE, mage.cards.g.GoblinWarrens.class)); cards.add(new SetCardInfo("Hand of Justice", 5, Rarity.RARE, mage.cards.h.HandOfJustice.class)); cards.add(new SetCardInfo("Havenwood Battleground", 96, Rarity.UNCOMMON, mage.cards.h.HavenwoodBattleground.class)); cards.add(new SetCardInfo("Heroism", 6, Rarity.UNCOMMON, mage.cards.h.Heroism.class)); - cards.add(new SetCardInfo("High Tide", "18a", Rarity.COMMON, HighTide.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("High Tide", "18b", Rarity.COMMON, HighTide.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("High Tide", "18c", Rarity.COMMON, HighTide.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("High Tide", "18a", Rarity.COMMON, mage.cards.h.HighTide.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("High Tide", "18b", Rarity.COMMON, mage.cards.h.HighTide.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("High Tide", "18c", Rarity.COMMON, mage.cards.h.HighTide.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hollow Trees", 97, Rarity.RARE, mage.cards.h.HollowTrees.class)); cards.add(new SetCardInfo("Homarid Shaman", 20, Rarity.RARE, mage.cards.h.HomaridShaman.class)); cards.add(new SetCardInfo("Homarid Spawning Bed", 21, Rarity.UNCOMMON, mage.cards.h.HomaridSpawningBed.class)); - cards.add(new SetCardInfo("Homarid Warrior", "22a", Rarity.COMMON, HomaridWarrior.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Homarid Warrior", "22b", Rarity.COMMON, HomaridWarrior.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Homarid Warrior", "22c", Rarity.COMMON, HomaridWarrior.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Homarid", "19a", Rarity.COMMON, Homarid.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Homarid", "19b", Rarity.COMMON, Homarid.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Homarid", "19c", Rarity.COMMON, Homarid.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Homarid", "19d", Rarity.COMMON, Homarid.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hymn to Tourach", "38a", Rarity.COMMON, HymnToTourach.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hymn to Tourach", "38b", Rarity.COMMON, HymnToTourach.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hymn to Tourach", "38c", Rarity.COMMON, HymnToTourach.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hymn to Tourach", "38d", Rarity.COMMON, HymnToTourach.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Infantry", "7a", Rarity.COMMON, IcatianInfantry.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Infantry", "7b", Rarity.COMMON, IcatianInfantry.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Infantry", "7c", Rarity.COMMON, IcatianInfantry.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Infantry", "7d", Rarity.COMMON, IcatianInfantry.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Javelineers", "8a", Rarity.COMMON, IcatianJavelineers.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Javelineers", "8b", Rarity.COMMON, IcatianJavelineers.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Javelineers", "8c", Rarity.COMMON, IcatianJavelineers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Homarid Warrior", "22a", Rarity.COMMON, mage.cards.h.HomaridWarrior.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Homarid Warrior", "22b", Rarity.COMMON, mage.cards.h.HomaridWarrior.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Homarid Warrior", "22c", Rarity.COMMON, mage.cards.h.HomaridWarrior.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Homarid", "19a", Rarity.COMMON, mage.cards.h.Homarid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Homarid", "19b", Rarity.COMMON, mage.cards.h.Homarid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Homarid", "19c", Rarity.COMMON, mage.cards.h.Homarid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Homarid", "19d", Rarity.COMMON, mage.cards.h.Homarid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Hymn to Tourach", "38a", Rarity.COMMON, mage.cards.h.HymnToTourach.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Hymn to Tourach", "38b", Rarity.COMMON, mage.cards.h.HymnToTourach.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Hymn to Tourach", "38c", Rarity.COMMON, mage.cards.h.HymnToTourach.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Hymn to Tourach", "38d", Rarity.COMMON, mage.cards.h.HymnToTourach.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Infantry", "7a", Rarity.COMMON, mage.cards.i.IcatianInfantry.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Infantry", "7b", Rarity.COMMON, mage.cards.i.IcatianInfantry.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Infantry", "7c", Rarity.COMMON, mage.cards.i.IcatianInfantry.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Infantry", "7d", Rarity.COMMON, mage.cards.i.IcatianInfantry.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Javelineers", "8a", Rarity.COMMON, mage.cards.i.IcatianJavelineers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Javelineers", "8b", Rarity.COMMON, mage.cards.i.IcatianJavelineers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Javelineers", "8c", Rarity.COMMON, mage.cards.i.IcatianJavelineers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Icatian Lieutenant", 9, Rarity.RARE, mage.cards.i.IcatianLieutenant.class)); - cards.add(new SetCardInfo("Icatian Moneychanger", "10a", Rarity.COMMON, IcatianMoneychanger.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Moneychanger", "10b", Rarity.COMMON, IcatianMoneychanger.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Moneychanger", "10c", Rarity.COMMON, IcatianMoneychanger.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Moneychanger", "10a", Rarity.COMMON, mage.cards.i.IcatianMoneychanger.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Moneychanger", "10b", Rarity.COMMON, mage.cards.i.IcatianMoneychanger.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Moneychanger", "10c", Rarity.COMMON, mage.cards.i.IcatianMoneychanger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Icatian Phalanx", 11, Rarity.UNCOMMON, mage.cards.i.IcatianPhalanx.class)); cards.add(new SetCardInfo("Icatian Priest", 12, Rarity.UNCOMMON, mage.cards.i.IcatianPriest.class)); - cards.add(new SetCardInfo("Icatian Scout", "13a", Rarity.COMMON, IcatianScout.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Scout", "13b", Rarity.COMMON, IcatianScout.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Scout", "13c", Rarity.COMMON, IcatianScout.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Icatian Scout", "13d", Rarity.COMMON, IcatianScout.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Scout", "13a", Rarity.COMMON, mage.cards.i.IcatianScout.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Scout", "13b", Rarity.COMMON, mage.cards.i.IcatianScout.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Scout", "13c", Rarity.COMMON, mage.cards.i.IcatianScout.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Icatian Scout", "13d", Rarity.COMMON, mage.cards.i.IcatianScout.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Icatian Skirmishers", 14, Rarity.RARE, mage.cards.i.IcatianSkirmishers.class)); cards.add(new SetCardInfo("Icatian Store", 98, Rarity.RARE, mage.cards.i.IcatianStore.class)); cards.add(new SetCardInfo("Icatian Town", 15, Rarity.RARE, mage.cards.i.IcatianTown.class)); cards.add(new SetCardInfo("Implements of Sacrifice", 88, Rarity.RARE, mage.cards.i.ImplementsOfSacrifice.class)); - cards.add(new SetCardInfo("Initiates of the Ebon Hand", "39a", Rarity.COMMON, InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Initiates of the Ebon Hand", "39b", Rarity.COMMON, InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Initiates of the Ebon Hand", "39c", Rarity.COMMON, InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Initiates of the Ebon Hand", "39a", Rarity.COMMON, mage.cards.i.InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Initiates of the Ebon Hand", "39b", Rarity.COMMON, mage.cards.i.InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Initiates of the Ebon Hand", "39c", Rarity.COMMON, mage.cards.i.InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Merseine", "23a", Rarity.COMMON, mage.cards.m.Merseine.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Merseine", "23b", Rarity.COMMON, mage.cards.m.Merseine.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Merseine", "23c", Rarity.COMMON, mage.cards.m.Merseine.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Merseine", "23d", Rarity.COMMON, mage.cards.m.Merseine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mindstab Thrull", "40a", Rarity.COMMON, MindstabThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mindstab Thrull", "40b", Rarity.COMMON, MindstabThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mindstab Thrull", "40c", Rarity.COMMON, MindstabThrull.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Necrite", "41a", Rarity.COMMON, Necrite.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Necrite", "41b", Rarity.COMMON, Necrite.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Necrite", "41c", Rarity.COMMON, Necrite.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Night Soil", "71a", Rarity.COMMON, NightSoil.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Night Soil", "71b", Rarity.COMMON, NightSoil.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Night Soil", "71c", Rarity.COMMON, NightSoil.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mindstab Thrull", "40a", Rarity.COMMON, mage.cards.m.MindstabThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mindstab Thrull", "40b", Rarity.COMMON, mage.cards.m.MindstabThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mindstab Thrull", "40c", Rarity.COMMON, mage.cards.m.MindstabThrull.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Necrite", "41a", Rarity.COMMON, mage.cards.n.Necrite.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Necrite", "41b", Rarity.COMMON, mage.cards.n.Necrite.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Necrite", "41c", Rarity.COMMON, mage.cards.n.Necrite.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Night Soil", "71a", Rarity.COMMON, mage.cards.n.NightSoil.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Night Soil", "71b", Rarity.COMMON, mage.cards.n.NightSoil.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Night Soil", "71c", Rarity.COMMON, mage.cards.n.NightSoil.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orcish Captain", 60, Rarity.UNCOMMON, mage.cards.o.OrcishCaptain.class)); - cards.add(new SetCardInfo("Orcish Spy", "61a", Rarity.COMMON, OrcishSpy.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Orcish Spy", "61b", Rarity.COMMON, OrcishSpy.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Orcish Spy", "61c", Rarity.COMMON, OrcishSpy.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Orcish Veteran", "62a", Rarity.COMMON, OrcishVeteran.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Orcish Veteran", "62b", Rarity.COMMON, OrcishVeteran.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Orcish Veteran", "62c", Rarity.COMMON, OrcishVeteran.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Orcish Veteran", "62d", Rarity.COMMON, OrcishVeteran.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Order of Leitbur", "16a", Rarity.COMMON, OrderOfLeitbur.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Order of Leitbur", "16b", Rarity.COMMON, OrderOfLeitbur.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Order of Leitbur", "16c", Rarity.COMMON, OrderOfLeitbur.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Order of the Ebon Hand", "42a", Rarity.COMMON, OrderOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Order of the Ebon Hand", "42b", Rarity.COMMON, OrderOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Order of the Ebon Hand", "42c", Rarity.COMMON, OrderOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Orcish Spy", "61a", Rarity.COMMON, mage.cards.o.OrcishSpy.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Orcish Spy", "61b", Rarity.COMMON, mage.cards.o.OrcishSpy.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Orcish Spy", "61c", Rarity.COMMON, mage.cards.o.OrcishSpy.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Orcish Veteran", "62a", Rarity.COMMON, mage.cards.o.OrcishVeteran.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Orcish Veteran", "62b", Rarity.COMMON, mage.cards.o.OrcishVeteran.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Orcish Veteran", "62c", Rarity.COMMON, mage.cards.o.OrcishVeteran.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Orcish Veteran", "62d", Rarity.COMMON, mage.cards.o.OrcishVeteran.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Order of Leitbur", "16a", Rarity.COMMON, mage.cards.o.OrderOfLeitbur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Order of Leitbur", "16b", Rarity.COMMON, mage.cards.o.OrderOfLeitbur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Order of Leitbur", "16c", Rarity.COMMON, mage.cards.o.OrderOfLeitbur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Order of the Ebon Hand", "42a", Rarity.COMMON, mage.cards.o.OrderOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Order of the Ebon Hand", "42b", Rarity.COMMON, mage.cards.o.OrderOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Order of the Ebon Hand", "42c", Rarity.COMMON, mage.cards.o.OrderOfTheEbonHand.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orgg", 63, Rarity.RARE, mage.cards.o.Orgg.class)); cards.add(new SetCardInfo("Raiding Party", 64, Rarity.UNCOMMON, mage.cards.r.RaidingParty.class)); cards.add(new SetCardInfo("Rainbow Vale", 99, Rarity.RARE, mage.cards.r.RainbowVale.class)); @@ -221,10 +190,10 @@ public final class FallenEmpires extends ExpansionSet { cards.add(new SetCardInfo("Thelon's Curse", 77, Rarity.RARE, mage.cards.t.ThelonsCurse.class)); cards.add(new SetCardInfo("Thelonite Druid", 78, Rarity.UNCOMMON, mage.cards.t.TheloniteDruid.class)); cards.add(new SetCardInfo("Thelonite Monk", 79, Rarity.RARE, mage.cards.t.TheloniteMonk.class)); - cards.add(new SetCardInfo("Thorn Thallid", "80a", Rarity.COMMON, ThornThallid.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Thorn Thallid", "80b", Rarity.COMMON, ThornThallid.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Thorn Thallid", "80c", Rarity.COMMON, ThornThallid.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Thorn Thallid", "80d", Rarity.COMMON, ThornThallid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Thorn Thallid", "80a", Rarity.COMMON, mage.cards.t.ThornThallid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Thorn Thallid", "80b", Rarity.COMMON, mage.cards.t.ThornThallid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Thorn Thallid", "80c", Rarity.COMMON, mage.cards.t.ThornThallid.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Thorn Thallid", "80d", Rarity.COMMON, mage.cards.t.ThornThallid.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thrull Champion", 44, Rarity.RARE, mage.cards.t.ThrullChampion.class)); cards.add(new SetCardInfo("Thrull Retainer", 45, Rarity.UNCOMMON, mage.cards.t.ThrullRetainer.class)); cards.add(new SetCardInfo("Thrull Wizard", 46, Rarity.UNCOMMON, mage.cards.t.ThrullWizard.class)); @@ -235,13 +204,13 @@ public final class FallenEmpires extends ExpansionSet { cards.add(new SetCardInfo("Tourach's Chant", 47, Rarity.UNCOMMON, mage.cards.t.TourachsChant.class)); cards.add(new SetCardInfo("Tourach's Gate", 48, Rarity.RARE, mage.cards.t.TourachsGate.class)); cards.add(new SetCardInfo("Vodalian Knights", 29, Rarity.RARE, mage.cards.v.VodalianKnights.class)); - cards.add(new SetCardInfo("Vodalian Mage", "30a", Rarity.COMMON, VodalianMage.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vodalian Mage", "30b", Rarity.COMMON, VodalianMage.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vodalian Mage", "30c", Rarity.COMMON, VodalianMage.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vodalian Soldiers", "31a", Rarity.COMMON, VodalianSoldiers.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vodalian Soldiers", "31b", Rarity.COMMON, VodalianSoldiers.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vodalian Soldiers", "31c", Rarity.COMMON, VodalianSoldiers.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vodalian Soldiers", "31d", Rarity.COMMON, VodalianSoldiers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vodalian Mage", "30a", Rarity.COMMON, mage.cards.v.VodalianMage.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vodalian Mage", "30b", Rarity.COMMON, mage.cards.v.VodalianMage.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vodalian Mage", "30c", Rarity.COMMON, mage.cards.v.VodalianMage.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vodalian Soldiers", "31a", Rarity.COMMON, mage.cards.v.VodalianSoldiers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vodalian Soldiers", "31b", Rarity.COMMON, mage.cards.v.VodalianSoldiers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vodalian Soldiers", "31c", Rarity.COMMON, mage.cards.v.VodalianSoldiers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vodalian Soldiers", "31d", Rarity.COMMON, mage.cards.v.VodalianSoldiers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vodalian War Machine", 32, Rarity.RARE, mage.cards.v.VodalianWarMachine.class)); cards.add(new SetCardInfo("Zelyon Sword", 91, Rarity.RARE, mage.cards.z.ZelyonSword.class)); } diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index beb34c641f..cc54407c64 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -1,18 +1,6 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.a.AbbeyMatron; -import mage.cards.a.AlibansTower; -import mage.cards.c.CemeteryGate; -import mage.cards.d.DrySpell; -import mage.cards.d.DwarvenTrader; -import mage.cards.f.FeastOfTheUnicorn; -import mage.cards.f.FolkOfAnHavva; -import mage.cards.m.MesaFalcon; -import mage.cards.r.ReefPirates; -import mage.cards.s.SengirBats; -import mage.cards.t.Torture; -import mage.cards.w.WillowFaerie; import mage.constants.Rarity; import mage.constants.SetType; @@ -38,11 +26,11 @@ public final class Homelands extends ExpansionSet { this.ratioBoosterMythic = 0; cards.add(new SetCardInfo("Abbey Gargoyles", 1, Rarity.UNCOMMON, mage.cards.a.AbbeyGargoyles.class)); - cards.add(new SetCardInfo("Abbey Matron", "2a", Rarity.COMMON, AbbeyMatron.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Abbey Matron", "2b", Rarity.COMMON, AbbeyMatron.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Abbey Matron", "2a", Rarity.COMMON, mage.cards.a.AbbeyMatron.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Abbey Matron", "2b", Rarity.COMMON, mage.cards.a.AbbeyMatron.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aether Storm", 21, Rarity.UNCOMMON, mage.cards.a.AetherStorm.class)); - cards.add(new SetCardInfo("Aliban's Tower", "61a", Rarity.COMMON, AlibansTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Aliban's Tower", "61b", Rarity.COMMON, AlibansTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Aliban's Tower", "61a", Rarity.COMMON, mage.cards.a.AlibansTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Aliban's Tower", "61b", Rarity.COMMON, mage.cards.a.AlibansTower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ambush Party", "63a", Rarity.COMMON, mage.cards.a.AmbushParty.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ambush Party", "63b", Rarity.COMMON, mage.cards.a.AmbushParty.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ambush", 62, Rarity.COMMON, mage.cards.a.Ambush.class)); @@ -71,8 +59,8 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Carapace", "84a", Rarity.COMMON, mage.cards.c.Carapace.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Carapace", "84b", Rarity.COMMON, mage.cards.c.Carapace.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Castle Sengir", 113, Rarity.UNCOMMON, mage.cards.c.CastleSengir.class)); - cards.add(new SetCardInfo("Cemetery Gate", "44a", Rarity.COMMON, CemeteryGate.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Cemetery Gate", "44b", Rarity.COMMON, CemeteryGate.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Cemetery Gate", "44a", Rarity.COMMON, mage.cards.c.CemeteryGate.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Cemetery Gate", "44b", Rarity.COMMON, mage.cards.c.CemeteryGate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chain Stasis", 23, Rarity.RARE, mage.cards.c.ChainStasis.class)); cards.add(new SetCardInfo("Chandler", 69, Rarity.COMMON, mage.cards.c.Chandler.class)); cards.add(new SetCardInfo("Clockwork Gnomes", 102, Rarity.COMMON, mage.cards.c.ClockworkGnomes.class)); @@ -85,21 +73,21 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Death Speakers", 7, Rarity.UNCOMMON, mage.cards.d.DeathSpeakers.class)); cards.add(new SetCardInfo("Didgeridoo", 105, Rarity.RARE, mage.cards.d.Didgeridoo.class)); cards.add(new SetCardInfo("Drudge Spell", 45, Rarity.UNCOMMON, mage.cards.d.DrudgeSpell.class)); - cards.add(new SetCardInfo("Dry Spell", "46a", Rarity.COMMON, DrySpell.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dry Spell", "46b", Rarity.COMMON, DrySpell.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dry Spell", "46a", Rarity.COMMON, mage.cards.d.DrySpell.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dry Spell", "46b", Rarity.COMMON, mage.cards.d.DrySpell.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dwarven Pony", 70, Rarity.RARE, mage.cards.d.DwarvenPony.class)); cards.add(new SetCardInfo("Dwarven Sea Clan", 71, Rarity.RARE, mage.cards.d.DwarvenSeaClan.class)); - cards.add(new SetCardInfo("Dwarven Trader", "72a", Rarity.COMMON, DwarvenTrader.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dwarven Trader", "72b", Rarity.COMMON, DwarvenTrader.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dwarven Trader", "72a", Rarity.COMMON, mage.cards.d.DwarvenTrader.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dwarven Trader", "72b", Rarity.COMMON, mage.cards.d.DwarvenTrader.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ebony Rhino", 106, Rarity.COMMON, mage.cards.e.EbonyRhino.class)); cards.add(new SetCardInfo("Eron the Relentless", 73, Rarity.UNCOMMON, mage.cards.e.EronTheRelentless.class)); cards.add(new SetCardInfo("Evaporate", 74, Rarity.UNCOMMON, mage.cards.e.Evaporate.class)); cards.add(new SetCardInfo("Faerie Noble", 86, Rarity.RARE, mage.cards.f.FaerieNoble.class)); - cards.add(new SetCardInfo("Feast of the Unicorn", "47a", Rarity.COMMON, FeastOfTheUnicorn.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Feast of the Unicorn", "47b", Rarity.COMMON, FeastOfTheUnicorn.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Feast of the Unicorn", "47a", Rarity.COMMON, mage.cards.f.FeastOfTheUnicorn.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Feast of the Unicorn", "47b", Rarity.COMMON, mage.cards.f.FeastOfTheUnicorn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Feroz's Ban", 107, Rarity.RARE, mage.cards.f.FerozsBan.class)); - cards.add(new SetCardInfo("Folk of An-Havva", "87a", Rarity.COMMON, FolkOfAnHavva.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Folk of An-Havva", "87b", Rarity.COMMON, FolkOfAnHavva.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Folk of An-Havva", "87a", Rarity.COMMON, mage.cards.f.FolkOfAnHavva.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Folk of An-Havva", "87b", Rarity.COMMON, mage.cards.f.FolkOfAnHavva.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forget", 26, Rarity.RARE, mage.cards.f.Forget.class)); cards.add(new SetCardInfo("Funeral March", 48, Rarity.COMMON, mage.cards.f.FuneralMarch.class)); cards.add(new SetCardInfo("Ghost Hounds", 49, Rarity.UNCOMMON, mage.cards.g.GhostHounds.class)); @@ -131,16 +119,16 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Memory Lapse", "32a", Rarity.COMMON, mage.cards.m.MemoryLapse.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Memory Lapse", "32b", Rarity.COMMON, mage.cards.m.MemoryLapse.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Merchant Scroll", 33, Rarity.COMMON, mage.cards.m.MerchantScroll.class)); - cards.add(new SetCardInfo("Mesa Falcon", "10a", Rarity.COMMON, MesaFalcon.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mesa Falcon", "10b", Rarity.COMMON, MesaFalcon.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mesa Falcon", "10a", Rarity.COMMON, mage.cards.m.MesaFalcon.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mesa Falcon", "10b", Rarity.COMMON, mage.cards.m.MesaFalcon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mystic Decree", 34, Rarity.RARE, mage.cards.m.MysticDecree.class)); cards.add(new SetCardInfo("Narwhal", 35, Rarity.RARE, mage.cards.n.Narwhal.class)); cards.add(new SetCardInfo("Orcish Mine", 78, Rarity.UNCOMMON, mage.cards.o.OrcishMine.class)); cards.add(new SetCardInfo("Primal Order", 92, Rarity.RARE, mage.cards.p.PrimalOrder.class)); cards.add(new SetCardInfo("Prophecy", 11, Rarity.COMMON, mage.cards.p.Prophecy.class)); cards.add(new SetCardInfo("Rashka the Slayer", 12, Rarity.UNCOMMON, mage.cards.r.RashkaTheSlayer.class)); - cards.add(new SetCardInfo("Reef Pirates", "36a", Rarity.COMMON, ReefPirates.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Reef Pirates", "36b", Rarity.COMMON, ReefPirates.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Reef Pirates", "36a", Rarity.COMMON, mage.cards.r.ReefPirates.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Reef Pirates", "36b", Rarity.COMMON, mage.cards.r.ReefPirates.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Renewal", 93, Rarity.COMMON, mage.cards.r.Renewal.class)); cards.add(new SetCardInfo("Retribution", 79, Rarity.UNCOMMON, mage.cards.r.Retribution.class)); cards.add(new SetCardInfo("Reveka, Wizard Savant", 37, Rarity.RARE, mage.cards.r.RevekaWizardSavant.class)); @@ -152,8 +140,8 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Sea Sprite", 38, Rarity.UNCOMMON, mage.cards.s.SeaSprite.class)); cards.add(new SetCardInfo("Sea Troll", 39, Rarity.UNCOMMON, mage.cards.s.SeaTroll.class)); cards.add(new SetCardInfo("Sengir Autocrat", 56, Rarity.UNCOMMON, mage.cards.s.SengirAutocrat.class)); - cards.add(new SetCardInfo("Sengir Bats", "57a", Rarity.COMMON, SengirBats.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sengir Bats", "57b", Rarity.COMMON, SengirBats.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sengir Bats", "57a", Rarity.COMMON, mage.cards.s.SengirBats.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sengir Bats", "57b", Rarity.COMMON, mage.cards.s.SengirBats.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Serra Aviary", 14, Rarity.RARE, mage.cards.s.SerraAviary.class)); cards.add(new SetCardInfo("Serra Bestiary", 15, Rarity.COMMON, mage.cards.s.SerraBestiary.class)); cards.add(new SetCardInfo("Serra Inquisitors", 16, Rarity.UNCOMMON, mage.cards.s.SerraInquisitors.class)); @@ -163,17 +151,17 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Shrink", "97b", Rarity.COMMON, mage.cards.s.Shrink.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Soraya the Falconer", 18, Rarity.RARE, mage.cards.s.SorayaTheFalconer.class)); cards.add(new SetCardInfo("Spectral Bears", 98, Rarity.UNCOMMON, mage.cards.s.SpectralBears.class)); - cards.add(new SetCardInfo("Torture", "59a", Rarity.COMMON, Torture.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Torture", "59b", Rarity.COMMON, Torture.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Torture", "59a", Rarity.COMMON, mage.cards.t.Torture.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Torture", "59b", Rarity.COMMON, mage.cards.t.Torture.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Trade Caravan", "19a", Rarity.COMMON, mage.cards.t.TradeCaravan.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Trade Caravan", "19b", Rarity.COMMON, mage.cards.t.TradeCaravan.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Truce", 20, Rarity.RARE, mage.cards.t.Truce.class)); cards.add(new SetCardInfo("Veldrane of Sengir", 60, Rarity.RARE, mage.cards.v.VeldraneOfSengir.class)); cards.add(new SetCardInfo("Wall of Kelp", 40, Rarity.RARE, mage.cards.w.WallOfKelp.class)); - cards.add(new SetCardInfo("Willow Faerie", "99a", Rarity.COMMON, WillowFaerie.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Willow Faerie", "99b", Rarity.COMMON, WillowFaerie.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Willow Faerie", "99a", Rarity.COMMON, mage.cards.w.WillowFaerie.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Willow Faerie", "99b", Rarity.COMMON, mage.cards.w.WillowFaerie.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Willow Priestess", 100, Rarity.RARE, mage.cards.w.WillowPriestess.class)); cards.add(new SetCardInfo("Winter Sky", 80, Rarity.RARE, mage.cards.w.WinterSky.class)); cards.add(new SetCardInfo("Wizards' School", 115, Rarity.UNCOMMON, mage.cards.w.WizardsSchool.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/MastersEdition.java b/Mage.Sets/src/mage/sets/MastersEdition.java index 942dd35def..99486fa757 100644 --- a/Mage.Sets/src/mage/sets/MastersEdition.java +++ b/Mage.Sets/src/mage/sets/MastersEdition.java @@ -2,23 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.b.BasalThrull; -import mage.cards.d.DwarvenSoldier; -import mage.cards.g.GoblinChirurgeon; -import mage.cards.g.GoblinGrenade; -import mage.cards.h.HighTide; -import mage.cards.h.HymnToTourach; -import mage.cards.m.MindstabThrull; -import mage.cards.o.OrderOfLeitbur; -import mage.cards.o.OrderOfTheEbonHand; -import mage.cards.o.Oubliette; -import mage.cards.p.PhyrexianWarBeast; -import mage.cards.t.ThornThallid; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author LevelX2 */ public final class MastersEdition extends ExpansionSet { @@ -38,6 +25,7 @@ public final class MastersEdition extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Adun Oakenshield", 141, Rarity.RARE, mage.cards.a.AdunOakenshield.class)); cards.add(new SetCardInfo("Amnesia", 29, Rarity.RARE, mage.cards.a.Amnesia.class)); cards.add(new SetCardInfo("Angry Mob", 1, Rarity.UNCOMMON, mage.cards.a.AngryMob.class)); @@ -54,7 +42,7 @@ public final class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Balduvian Horde", 86, Rarity.RARE, mage.cards.b.BalduvianHorde.class)); cards.add(new SetCardInfo("Ball Lightning", 87, Rarity.RARE, mage.cards.b.BallLightning.class)); cards.add(new SetCardInfo("Baron Sengir", 58, Rarity.RARE, mage.cards.b.BaronSengir.class)); - cards.add(new SetCardInfo("Basal Thrull", 59, Rarity.COMMON, BasalThrull.class)); + cards.add(new SetCardInfo("Basal Thrull", 59, Rarity.COMMON, mage.cards.b.BasalThrull.class)); cards.add(new SetCardInfo("Benalish Hero", 5, Rarity.COMMON, mage.cards.b.BenalishHero.class)); cards.add(new SetCardInfo("Berserk", 114, Rarity.RARE, mage.cards.b.Berserk.class)); cards.add(new SetCardInfo("Bestial Fury", 88, Rarity.COMMON, mage.cards.b.BestialFury.class)); @@ -83,7 +71,7 @@ public final class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Dragon Engine", 156, Rarity.COMMON, mage.cards.d.DragonEngine.class)); cards.add(new SetCardInfo("Dust to Dust", 10, Rarity.COMMON, mage.cards.d.DustToDust.class)); cards.add(new SetCardInfo("Dwarven Catapult", 91, Rarity.UNCOMMON, mage.cards.d.DwarvenCatapult.class)); - cards.add(new SetCardInfo("Dwarven Soldier", 92, Rarity.COMMON, DwarvenSoldier.class)); + cards.add(new SetCardInfo("Dwarven Soldier", 92, Rarity.COMMON, mage.cards.d.DwarvenSoldier.class)); cards.add(new SetCardInfo("Eater of the Dead", 67, Rarity.UNCOMMON, mage.cards.e.EaterOfTheDead.class)); cards.add(new SetCardInfo("Elder Land Wurm", 11, Rarity.UNCOMMON, mage.cards.e.ElderLandWurm.class)); cards.add(new SetCardInfo("Erg Raiders", 68, Rarity.COMMON, mage.cards.e.ErgRaiders.class)); @@ -101,8 +89,8 @@ public final class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Fyndhorn Elves", 118, Rarity.COMMON, mage.cards.f.FyndhornElves.class)); cards.add(new SetCardInfo("Ghazban Ogre", 120, Rarity.COMMON, mage.cards.g.GhazbanOgre.class)); cards.add(new SetCardInfo("Giant Tortoise", 34, Rarity.COMMON, mage.cards.g.GiantTortoise.class)); - cards.add(new SetCardInfo("Goblin Chirurgeon", 94, Rarity.COMMON, GoblinChirurgeon.class)); - cards.add(new SetCardInfo("Goblin Grenade", 95, Rarity.UNCOMMON, GoblinGrenade.class)); + cards.add(new SetCardInfo("Goblin Chirurgeon", 94, Rarity.COMMON, mage.cards.g.GoblinChirurgeon.class)); + cards.add(new SetCardInfo("Goblin Grenade", 95, Rarity.UNCOMMON, mage.cards.g.GoblinGrenade.class)); cards.add(new SetCardInfo("Goblin Mutant", 96, Rarity.UNCOMMON, mage.cards.g.GoblinMutant.class)); cards.add(new SetCardInfo("Goblins of the Flarg", 98, Rarity.COMMON, mage.cards.g.GoblinsOfTheFlarg.class)); cards.add(new SetCardInfo("Goblin Wizard", 97, Rarity.RARE, mage.cards.g.GoblinWizard.class)); @@ -111,14 +99,14 @@ public final class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Hallowed Ground", 14, Rarity.UNCOMMON, mage.cards.h.HallowedGround.class)); cards.add(new SetCardInfo("Hand of Justice", 15, Rarity.RARE, mage.cards.h.HandOfJustice.class)); cards.add(new SetCardInfo("Hecatomb", 71, Rarity.RARE, mage.cards.h.Hecatomb.class)); - cards.add(new SetCardInfo("High Tide", 35, Rarity.UNCOMMON, HighTide.class)); + cards.add(new SetCardInfo("High Tide", 35, Rarity.UNCOMMON, mage.cards.h.HighTide.class)); cards.add(new SetCardInfo("Holy Light", 16, Rarity.COMMON, mage.cards.h.HolyLight.class)); cards.add(new SetCardInfo("Homarid Spawning Bed", 36, Rarity.UNCOMMON, mage.cards.h.HomaridSpawningBed.class)); cards.add(new SetCardInfo("Hungry Mist", 121, Rarity.COMMON, mage.cards.h.HungryMist.class)); cards.add(new SetCardInfo("Hyalopterous Lemure", 72, Rarity.COMMON, mage.cards.h.HyalopterousLemure.class)); cards.add(new SetCardInfo("Hydroblast", 37, Rarity.COMMON, mage.cards.h.Hydroblast.class)); cards.add(new SetCardInfo("Hymn of Rebirth", 146, Rarity.UNCOMMON, mage.cards.h.HymnOfRebirth.class)); - cards.add(new SetCardInfo("Hymn to Tourach", 73, Rarity.UNCOMMON, HymnToTourach.class)); + cards.add(new SetCardInfo("Hymn to Tourach", 73, Rarity.UNCOMMON, mage.cards.h.HymnToTourach.class)); cards.add(new SetCardInfo("Icatian Lieutenant", 17, Rarity.COMMON, mage.cards.i.IcatianLieutenant.class)); cards.add(new SetCardInfo("Icatian Town", 18, Rarity.UNCOMMON, mage.cards.i.IcatianTown.class)); cards.add(new SetCardInfo("Ice Storm", 122, Rarity.UNCOMMON, mage.cards.i.IceStorm.class)); @@ -145,7 +133,7 @@ public final class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Mana Flare", 103, Rarity.RARE, mage.cards.m.ManaFlare.class)); cards.add(new SetCardInfo("Marton Stromgald", 104, Rarity.RARE, mage.cards.m.MartonStromgald.class)); cards.add(new SetCardInfo("Mesa Pegasus", 20, Rarity.COMMON, mage.cards.m.MesaPegasus.class)); - cards.add(new SetCardInfo("Mindstab Thrull", 76, Rarity.COMMON, MindstabThrull.class)); + cards.add(new SetCardInfo("Mindstab Thrull", 76, Rarity.COMMON, mage.cards.m.MindstabThrull.class)); cards.add(new SetCardInfo("Mirror Universe", 159, Rarity.RARE, mage.cards.m.MirrorUniverse.class)); cards.add(new SetCardInfo("Mishra's Factory", 178, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); cards.add(new SetCardInfo("Moat", 21, Rarity.RARE, mage.cards.m.Moat.class)); @@ -159,15 +147,15 @@ public final class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Nevinyrral's Disk", 160, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class)); cards.add(new SetCardInfo("Onulet", 161, Rarity.COMMON, mage.cards.o.Onulet.class)); cards.add(new SetCardInfo("Orcish Mechanics", 106, Rarity.UNCOMMON, mage.cards.o.OrcishMechanics.class)); - cards.add(new SetCardInfo("Order of Leitbur", 22, Rarity.COMMON, OrderOfLeitbur.class)); - cards.add(new SetCardInfo("Order of the Ebon Hand", 78, Rarity.COMMON, OrderOfTheEbonHand.class)); - cards.add(new SetCardInfo("Oubliette", 79, Rarity.COMMON, Oubliette.class)); + cards.add(new SetCardInfo("Order of Leitbur", 22, Rarity.COMMON, mage.cards.o.OrderOfLeitbur.class)); + cards.add(new SetCardInfo("Order of the Ebon Hand", 78, Rarity.COMMON, mage.cards.o.OrderOfTheEbonHand.class)); + cards.add(new SetCardInfo("Oubliette", 79, Rarity.COMMON, mage.cards.o.Oubliette.class)); cards.add(new SetCardInfo("Paralyze", 80, Rarity.COMMON, mage.cards.p.Paralyze.class)); cards.add(new SetCardInfo("Petra Sphinx", 23, Rarity.RARE, mage.cards.p.PetraSphinx.class)); cards.add(new SetCardInfo("Phantom Monster", 43, Rarity.COMMON, mage.cards.p.PhantomMonster.class)); cards.add(new SetCardInfo("Phelddagrif", 150, Rarity.RARE, mage.cards.p.Phelddagrif.class)); cards.add(new SetCardInfo("Phyrexian Boon", 81, Rarity.COMMON, mage.cards.p.PhyrexianBoon.class)); - cards.add(new SetCardInfo("Phyrexian War Beast", 162, Rarity.UNCOMMON, PhyrexianWarBeast.class)); + cards.add(new SetCardInfo("Phyrexian War Beast", 162, Rarity.UNCOMMON, mage.cards.p.PhyrexianWarBeast.class)); cards.add(new SetCardInfo("Plains", 181, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 182, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 183, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); @@ -208,7 +196,7 @@ public final class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Telekinesis", 52, Rarity.COMMON, mage.cards.t.Telekinesis.class)); cards.add(new SetCardInfo("Thawing Glaciers", 180, Rarity.RARE, mage.cards.t.ThawingGlaciers.class)); cards.add(new SetCardInfo("Thicket Basilisk", 134, Rarity.UNCOMMON, mage.cards.t.ThicketBasilisk.class)); - cards.add(new SetCardInfo("Thorn Thallid", 135, Rarity.COMMON, ThornThallid.class)); + cards.add(new SetCardInfo("Thorn Thallid", 135, Rarity.COMMON, mage.cards.t.ThornThallid.class)); cards.add(new SetCardInfo("Thrull Champion", 83, Rarity.RARE, mage.cards.t.ThrullChampion.class)); cards.add(new SetCardInfo("Thrull Retainer", 84, Rarity.COMMON, mage.cards.t.ThrullRetainer.class)); cards.add(new SetCardInfo("Thunder Spirit", 27, Rarity.UNCOMMON, mage.cards.t.ThunderSpirit.class)); @@ -231,5 +219,4 @@ public final class MastersEdition extends ExpansionSet { cards.add(new SetCardInfo("Ydwen Efreet", 112, Rarity.RARE, mage.cards.y.YdwenEfreet.class)); cards.add(new SetCardInfo("Zuran Orb", 174, Rarity.UNCOMMON, mage.cards.z.ZuranOrb.class)); } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/MastersEditionIII.java b/Mage.Sets/src/mage/sets/MastersEditionIII.java index 199b32e732..779517679c 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIII.java @@ -2,12 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.f.FeveredStrength; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author LevelX2 */ public final class MastersEditionIII extends ExpansionSet { @@ -27,6 +25,7 @@ public final class MastersEditionIII extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Active Volcano", 85, Rarity.UNCOMMON, mage.cards.a.ActiveVolcano.class)); cards.add(new SetCardInfo("Akron Legionnaire", 1, Rarity.RARE, mage.cards.a.AkronLegionnaire.class)); cards.add(new SetCardInfo("Alabaster Potion", 2, Rarity.UNCOMMON, mage.cards.a.AlabasterPotion.class)); @@ -87,7 +86,7 @@ public final class MastersEditionIII extends ExpansionSet { cards.add(new SetCardInfo("False Defeat", 11, Rarity.UNCOMMON, mage.cards.f.FalseDefeat.class)); cards.add(new SetCardInfo("Famine", 65, Rarity.UNCOMMON, mage.cards.f.Famine.class)); cards.add(new SetCardInfo("Fellwar Stone", 195, Rarity.COMMON, mage.cards.f.FellwarStone.class)); - cards.add(new SetCardInfo("Fevered Strength", 66, Rarity.COMMON, FeveredStrength.class)); + cards.add(new SetCardInfo("Fevered Strength", 66, Rarity.COMMON, mage.cards.f.FeveredStrength.class)); cards.add(new SetCardInfo("Fire Ambush", 97, Rarity.COMMON, mage.cards.f.FireAmbush.class)); cards.add(new SetCardInfo("Fire Drake", 98, Rarity.COMMON, mage.cards.f.FireDrake.class)); cards.add(new SetCardInfo("Fire Sprites", 118, Rarity.COMMON, mage.cards.f.FireSprites.class)); @@ -247,5 +246,4 @@ public final class MastersEditionIII extends ExpansionSet { cards.add(new SetCardInfo("Zhang Fei, Fierce Warrior", 28, Rarity.UNCOMMON, mage.cards.z.ZhangFeiFierceWarrior.class)); cards.add(new SetCardInfo("Zodiac Dragon", 112, Rarity.RARE, mage.cards.z.ZodiacDragon.class)); } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/MastersEditionIV.java b/Mage.Sets/src/mage/sets/MastersEditionIV.java index 505fa1bd67..ba6d2eb7e9 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIV.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIV.java @@ -2,8 +2,6 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.a.AesthirGlider; -import mage.cards.e.EliteCatWarrior; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; @@ -14,7 +12,6 @@ import java.util.ArrayList; import java.util.List; /** - * * @author LevelX2 */ public final class MastersEditionIV extends ExpansionSet { @@ -37,8 +34,9 @@ public final class MastersEditionIV extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 0; this.ratioBoosterSpecialLand = 1; // replace all basic lands + cards.add(new SetCardInfo("Acid Rain", 36, Rarity.RARE, mage.cards.a.AcidRain.class)); - cards.add(new SetCardInfo("Aesthir Glider", 176, Rarity.COMMON, AesthirGlider.class)); + cards.add(new SetCardInfo("Aesthir Glider", 176, Rarity.COMMON, mage.cards.a.AesthirGlider.class)); cards.add(new SetCardInfo("Air Elemental", 37, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); cards.add(new SetCardInfo("Al-abara's Carpet", 177, Rarity.RARE, mage.cards.a.AlAbarasCarpet.class)); cards.add(new SetCardInfo("Alaborn Musketeer", 1, Rarity.COMMON, mage.cards.a.AlabornMusketeer.class)); @@ -113,7 +111,7 @@ public final class MastersEditionIV extends ExpansionSet { cards.add(new SetCardInfo("Ebony Horse", 198, Rarity.COMMON, mage.cards.e.EbonyHorse.class)); cards.add(new SetCardInfo("Ebony Rhino", 199, Rarity.COMMON, mage.cards.e.EbonyRhino.class)); cards.add(new SetCardInfo("Elephant Graveyard", 244, Rarity.UNCOMMON, mage.cards.e.ElephantGraveyard.class)); - cards.add(new SetCardInfo("Elite Cat Warrior", 151, Rarity.COMMON, EliteCatWarrior.class)); + cards.add(new SetCardInfo("Elite Cat Warrior", 151, Rarity.COMMON, mage.cards.e.EliteCatWarrior.class)); cards.add(new SetCardInfo("Energy Flux", 48, Rarity.UNCOMMON, mage.cards.e.EnergyFlux.class)); cards.add(new SetCardInfo("Eye for an Eye", 12, Rarity.RARE, mage.cards.e.EyeForAnEye.class)); cards.add(new SetCardInfo("False Summoning", 49, Rarity.COMMON, mage.cards.f.FalseSummoning.class)); @@ -317,5 +315,4 @@ public final class MastersEditionIV extends ExpansionSet { return new ArrayList<>(savedSpecialLand); } - } \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/MediaInserts.java b/Mage.Sets/src/mage/sets/MediaInserts.java index 63974d8351..2a3f0c2bf9 100644 --- a/Mage.Sets/src/mage/sets/MediaInserts.java +++ b/Mage.Sets/src/mage/sets/MediaInserts.java @@ -2,7 +2,6 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.h.HighTide; import mage.constants.Rarity; import mage.constants.SetType; @@ -18,6 +17,7 @@ public final class MediaInserts extends ExpansionSet { super("Media Inserts", "MBP", ExpansionSet.buildDate(1990, 1, 1), SetType.PROMOTIONAL); this.hasBoosters = false; this.hasBasicLands = false; + cards.add(new SetCardInfo("Acquire", 83, Rarity.RARE, mage.cards.a.Acquire.class)); cards.add(new SetCardInfo("Aeronaut Tinkerer", 118, Rarity.COMMON, mage.cards.a.AeronautTinkerer.class)); cards.add(new SetCardInfo("Ajani, Caller of the Pride", 72, Rarity.MYTHIC, mage.cards.a.AjaniCallerOfThePride.class)); @@ -102,7 +102,7 @@ public final class MediaInserts extends ExpansionSet { cards.add(new SetCardInfo("Hamletback Goliath", 71, Rarity.RARE, mage.cards.h.HamletbackGoliath.class)); cards.add(new SetCardInfo("Harbinger of the Hunt", 116, Rarity.SPECIAL, mage.cards.h.HarbingerOfTheHunt.class)); cards.add(new SetCardInfo("Hero of Goma Fada", 136, Rarity.SPECIAL, mage.cards.h.HeroOfGomaFada.class)); - cards.add(new SetCardInfo("High Tide", 80, Rarity.COMMON, HighTide.class)); + cards.add(new SetCardInfo("High Tide", 80, Rarity.COMMON, mage.cards.h.HighTide.class)); cards.add(new SetCardInfo("Hixus, Prison Warden", 126, Rarity.SPECIAL, mage.cards.h.HixusPrisonWarden.class)); cards.add(new SetCardInfo("Honored Hierarch", 129, Rarity.SPECIAL, mage.cards.h.HonoredHierarch.class)); cards.add(new SetCardInfo("Honor of the Pure", 20, Rarity.RARE, mage.cards.h.HonorOfThePure.class)); @@ -211,4 +211,4 @@ public final class MediaInserts extends ExpansionSet { cards.add(new SetCardInfo("Windseeker Centaur", 7, Rarity.SPECIAL, mage.cards.w.WindseekerCentaur.class)); cards.add(new SetCardInfo("Xathrid Necromancer", 91, Rarity.SPECIAL, mage.cards.x.XathridNecromancer.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index bfe9319576..4a45154f42 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -1,12 +1,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.d.Delirium; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class Mirage extends ExpansionSet { @@ -26,6 +24,7 @@ public final class Mirage extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abyssal Hunter", 103, Rarity.RARE, mage.cards.a.AbyssalHunter.class)); cards.add(new SetCardInfo("Afiya Grove", 205, Rarity.RARE, mage.cards.a.AfiyaGrove.class)); cards.add(new SetCardInfo("Afterlife", 1, Rarity.UNCOMMON, mage.cards.a.Afterlife.class)); @@ -84,7 +83,7 @@ public final class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Dark Banishing", 115, Rarity.COMMON, mage.cards.d.DarkBanishing.class)); cards.add(new SetCardInfo("Dark Ritual", 116, Rarity.COMMON, mage.cards.d.DarkRitual.class)); cards.add(new SetCardInfo("Dazzling Beauty", 8, Rarity.COMMON, mage.cards.d.DazzlingBeauty.class)); - cards.add(new SetCardInfo("Delirium", 260, Rarity.UNCOMMON, Delirium.class)); + cards.add(new SetCardInfo("Delirium", 260, Rarity.UNCOMMON, mage.cards.d.Delirium.class)); cards.add(new SetCardInfo("Dirtwater Wraith", 117, Rarity.COMMON, mage.cards.d.DirtwaterWraith.class)); cards.add(new SetCardInfo("Disempower", 9, Rarity.COMMON, mage.cards.d.Disempower.class)); cards.add(new SetCardInfo("Disenchant", 10, Rarity.COMMON, mage.cards.d.Disenchant.class)); @@ -330,4 +329,4 @@ public final class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Zombie Mob", 153, Rarity.UNCOMMON, mage.cards.z.ZombieMob.class)); cards.add(new SetCardInfo("Zuberi, Golden Feather", 51, Rarity.RARE, mage.cards.z.ZuberiGoldenFeather.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/NinthEdition.java b/Mage.Sets/src/mage/sets/NinthEdition.java index 02a6e2dbc2..93759bbb0f 100644 --- a/Mage.Sets/src/mage/sets/NinthEdition.java +++ b/Mage.Sets/src/mage/sets/NinthEdition.java @@ -1,8 +1,6 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.f.FishliverOil; -import mage.cards.r.RukhEgg; import mage.constants.Rarity; import mage.constants.SetType; @@ -22,6 +20,7 @@ public final class NinthEdition extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Adarkar Wastes", 317, Rarity.RARE, mage.cards.a.AdarkarWastes.class)); cards.add(new SetCardInfo("Air Elemental", 58, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); cards.add(new SetCardInfo("Aladdin's Ring", 286, Rarity.RARE, mage.cards.a.AladdinsRing.class)); @@ -110,7 +109,7 @@ public final class NinthEdition extends ExpansionSet { cards.add(new SetCardInfo("Festering Goblin", 130, Rarity.COMMON, mage.cards.f.FesteringGoblin.class)); cards.add(new SetCardInfo("Final Punishment", 131, Rarity.RARE, mage.cards.f.FinalPunishment.class)); cards.add(new SetCardInfo("Firebreathing", 181, Rarity.COMMON, mage.cards.f.Firebreathing.class)); - cards.add(new SetCardInfo("Fishliver Oil", 77, Rarity.COMMON, FishliverOil.class)); + cards.add(new SetCardInfo("Fishliver Oil", 77, Rarity.COMMON, mage.cards.f.FishliverOil.class)); cards.add(new SetCardInfo("Flame Wave", 182, Rarity.UNCOMMON, mage.cards.f.FlameWave.class)); cards.add(new SetCardInfo("Flashfires", 183, Rarity.UNCOMMON, mage.cards.f.Flashfires.class)); cards.add(new SetCardInfo("Fleeting Image", 78, Rarity.RARE, mage.cards.f.FleetingImage.class)); @@ -266,7 +265,7 @@ public final class NinthEdition extends ExpansionSet { cards.add(new SetCardInfo("Rootbreaker Wurm", 267, Rarity.UNCOMMON, mage.cards.r.RootbreakerWurm.class)); cards.add(new SetCardInfo("Rootwalla", 268, Rarity.COMMON, mage.cards.r.Rootwalla.class)); cards.add(new SetCardInfo("Royal Assassin", 159, Rarity.RARE, mage.cards.r.RoyalAssassin.class)); - cards.add(new SetCardInfo("Rukh Egg", 214, Rarity.RARE, RukhEgg.class)); + cards.add(new SetCardInfo("Rukh Egg", 214, Rarity.RARE, mage.cards.r.RukhEgg.class)); cards.add(new SetCardInfo("Sacred Ground", 37, Rarity.RARE, mage.cards.s.SacredGround.class)); cards.add(new SetCardInfo("Sacred Nectar", 38, Rarity.COMMON, mage.cards.s.SacredNectar.class)); cards.add(new SetCardInfo("Sage Aven", 95, Rarity.COMMON, mage.cards.s.SageAven.class)); @@ -372,5 +371,4 @@ public final class NinthEdition extends ExpansionSet { cards.add(new SetCardInfo("Zombify", 171, Rarity.UNCOMMON, mage.cards.z.Zombify.class)); cards.add(new SetCardInfo("Zur's Weirding", 114, Rarity.RARE, mage.cards.z.ZursWeirding.class)); } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/NinthEditionBox.java b/Mage.Sets/src/mage/sets/NinthEditionBox.java index 06337351eb..91b9c31511 100644 --- a/Mage.Sets/src/mage/sets/NinthEditionBox.java +++ b/Mage.Sets/src/mage/sets/NinthEditionBox.java @@ -15,6 +15,7 @@ public final class NinthEditionBox extends ExpansionSet { private NinthEditionBox() { super("Ninth Edition Box", "9EB", ExpansionSet.buildDate(2005, 7, 29), SetType.CORE); this.hasBoosters = false; + this.hasBasicLands = false; cards.add(new SetCardInfo("Coral Eel", 3, Rarity.COMMON, mage.cards.c.CoralEel.class)); cards.add(new SetCardInfo("Eager Cadet", 1, Rarity.COMMON, mage.cards.e.EagerCadet.class)); diff --git a/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java b/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java index 66ec171f85..b0c75fda4a 100644 --- a/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java +++ b/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java @@ -9,7 +9,6 @@ import mage.cards.ExpansionSet; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; -import mage.cards.w.Wastes; import mage.constants.Rarity; import mage.constants.SetType; @@ -41,6 +40,7 @@ public final class OathOfTheGatewatch extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 8; this.ratioBoosterSpecialLand = 48; + cards.add(new SetCardInfo("Abstruse Interference", 40, Rarity.COMMON, mage.cards.a.AbstruseInterference.class)); cards.add(new SetCardInfo("Affa Protector", 14, Rarity.COMMON, mage.cards.a.AffaProtector.class)); cards.add(new SetCardInfo("Akoum Flameseeker", 101, Rarity.COMMON, mage.cards.a.AkoumFlameseeker.class)); @@ -217,10 +217,10 @@ public final class OathOfTheGatewatch extends ExpansionSet { cards.add(new SetCardInfo("Wandering Fumarole", 182, Rarity.RARE, mage.cards.w.WanderingFumarole.class)); cards.add(new SetCardInfo("Warden of Geometries", 11, Rarity.COMMON, mage.cards.w.WardenOfGeometries.class)); cards.add(new SetCardInfo("Warping Wail", 12, Rarity.UNCOMMON, mage.cards.w.WarpingWail.class)); - cards.add(new SetCardInfo("Wastes", "183a", Rarity.LAND, Wastes.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Wastes", "183b", Rarity.LAND, Wastes.class, FULL_ART_BFZ_VARIOUS)); - cards.add(new SetCardInfo("Wastes", "184a", Rarity.LAND, Wastes.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Wastes", "184b", Rarity.LAND, Wastes.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Wastes", "183a", Rarity.LAND, mage.cards.w.Wastes.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Wastes", "183b", Rarity.LAND, mage.cards.w.Wastes.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Wastes", "184a", Rarity.LAND, mage.cards.w.Wastes.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Wastes", "184b", Rarity.LAND, mage.cards.w.Wastes.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Weapons Trainer", 160, Rarity.UNCOMMON, mage.cards.w.WeaponsTrainer.class)); cards.add(new SetCardInfo("Witness the End", 82, Rarity.COMMON, mage.cards.w.WitnessTheEnd.class)); cards.add(new SetCardInfo("World Breaker", 126, Rarity.MYTHIC, mage.cards.w.WorldBreaker.class)); @@ -241,4 +241,4 @@ public final class OathOfTheGatewatch extends ExpansionSet { return new ArrayList<>(savedSpecialLand); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Planeshift.java b/Mage.Sets/src/mage/sets/Planeshift.java index eec82b0af4..57a70190de 100644 --- a/Mage.Sets/src/mage/sets/Planeshift.java +++ b/Mage.Sets/src/mage/sets/Planeshift.java @@ -2,14 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.e.ErtaiTheCorrupted; -import mage.cards.s.SkyshipWeatherlight; -import mage.cards.t.TahngarthTalruumHero; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class Planeshift extends ExpansionSet { @@ -31,6 +27,7 @@ public final class Planeshift extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Allied Strategies", 20, Rarity.UNCOMMON, mage.cards.a.AlliedStrategies.class)); cards.add(new SetCardInfo("Alpha Kavu", 77, Rarity.UNCOMMON, mage.cards.a.AlphaKavu.class)); cards.add(new SetCardInfo("Ancient Spider", 96, Rarity.RARE, mage.cards.a.AncientSpider.class)); @@ -61,8 +58,8 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Dromar's Charm", 105, Rarity.UNCOMMON, mage.cards.d.DromarsCharm.class)); cards.add(new SetCardInfo("Eladamri's Call", 106, Rarity.RARE, mage.cards.e.EladamrisCall.class)); cards.add(new SetCardInfo("Ertai's Trickery", 24, Rarity.UNCOMMON, mage.cards.e.ErtaisTrickery.class)); - cards.add(new SetCardInfo("Ertai, the Corrupted", "107a", Rarity.RARE, ErtaiTheCorrupted.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ertai, the Corrupted", "107b", Rarity.RARE, ErtaiTheCorrupted.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ertai, the Corrupted", "107a", Rarity.RARE, mage.cards.e.ErtaiTheCorrupted.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ertai, the Corrupted", "107b", Rarity.RARE, mage.cards.e.ErtaiTheCorrupted.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Escape Routes", 25, Rarity.COMMON, mage.cards.e.EscapeRoutes.class)); cards.add(new SetCardInfo("Exotic Disease", 43, Rarity.UNCOMMON, mage.cards.e.ExoticDisease.class)); cards.add(new SetCardInfo("Falling Timber", 79, Rarity.COMMON, mage.cards.f.FallingTimber.class)); @@ -139,8 +136,8 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Singe", 71, Rarity.COMMON, mage.cards.s.Singe.class)); cards.add(new SetCardInfo("Sinister Strength", 54, Rarity.COMMON, mage.cards.s.SinisterStrength.class)); cards.add(new SetCardInfo("Sisay's Ingenuity", 33, Rarity.COMMON, mage.cards.s.SisaysIngenuity.class)); - cards.add(new SetCardInfo("Skyship Weatherlight", "133a", Rarity.RARE, SkyshipWeatherlight.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Skyship Weatherlight", "133b", Rarity.RARE, SkyshipWeatherlight.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Skyship Weatherlight", "133a", Rarity.RARE, mage.cards.s.SkyshipWeatherlight.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Skyship Weatherlight", "133b", Rarity.RARE, mage.cards.s.SkyshipWeatherlight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Skyshroud Blessing", 92, Rarity.UNCOMMON, mage.cards.s.SkyshroudBlessing.class)); cards.add(new SetCardInfo("Slay", 55, Rarity.UNCOMMON, mage.cards.s.Slay.class)); cards.add(new SetCardInfo("Sleeping Potion", 34, Rarity.COMMON, mage.cards.s.SleepingPotion.class)); @@ -157,8 +154,8 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Sunscape Battlemage", 16, Rarity.UNCOMMON, mage.cards.s.SunscapeBattlemage.class)); cards.add(new SetCardInfo("Sunscape Familiar", 17, Rarity.COMMON, mage.cards.s.SunscapeFamiliar.class)); cards.add(new SetCardInfo("Surprise Deployment", 18, Rarity.UNCOMMON, mage.cards.s.SurpriseDeployment.class)); - cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74a", Rarity.RARE, TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74b", Rarity.RARE, TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74a", Rarity.RARE, mage.cards.t.TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74b", Rarity.RARE, mage.cards.t.TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Terminal Moraine", 142, Rarity.UNCOMMON, mage.cards.t.TerminalMoraine.class)); cards.add(new SetCardInfo("Terminate", 128, Rarity.COMMON, mage.cards.t.Terminate.class)); cards.add(new SetCardInfo("Thornscape Battlemage", 94, Rarity.UNCOMMON, mage.cards.t.ThornscapeBattlemage.class)); @@ -173,4 +170,4 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Warped Devotion", 57, Rarity.UNCOMMON, mage.cards.w.WarpedDevotion.class)); cards.add(new SetCardInfo("Waterspout Elemental", 38, Rarity.RARE, mage.cards.w.WaterspoutElemental.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Portal.java b/Mage.Sets/src/mage/sets/Portal.java index 81162ed77c..822317e27b 100644 --- a/Mage.Sets/src/mage/sets/Portal.java +++ b/Mage.Sets/src/mage/sets/Portal.java @@ -2,14 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.d.DrySpell; -import mage.cards.e.EliteCatWarrior; -import mage.cards.w.WarriorsCharge; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author Plopman */ public final class Portal extends ExpansionSet { @@ -17,7 +13,6 @@ public final class Portal extends ExpansionSet { private static final Portal instance = new Portal(); /** - * * @return */ public static Portal getInstance() { @@ -34,6 +29,7 @@ public final class Portal extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Alabaster Dragon", 1, Rarity.RARE, mage.cards.a.AlabasterDragon.class)); cards.add(new SetCardInfo("Alluring Scent", 157, Rarity.RARE, mage.cards.a.AlluringScent.class)); cards.add(new SetCardInfo("Anaconda", "158a", Rarity.UNCOMMON, mage.cards.a.Anaconda.class, NON_FULL_USE_VARIOUS)); @@ -86,11 +82,11 @@ public final class Portal extends ExpansionSet { cards.add(new SetCardInfo("Djinn of the Lamp", 52, Rarity.RARE, mage.cards.d.DjinnOfTheLamp.class)); cards.add(new SetCardInfo("Dread Charge", 88, Rarity.RARE, mage.cards.d.DreadCharge.class)); cards.add(new SetCardInfo("Dread Reaper", 89, Rarity.RARE, mage.cards.d.DreadReaper.class)); - cards.add(new SetCardInfo("Dry Spell", 90, Rarity.UNCOMMON, DrySpell.class)); + cards.add(new SetCardInfo("Dry Spell", 90, Rarity.UNCOMMON, mage.cards.d.DrySpell.class)); cards.add(new SetCardInfo("Earthquake", 124, Rarity.RARE, mage.cards.e.Earthquake.class)); cards.add(new SetCardInfo("Ebon Dragon", 91, Rarity.RARE, mage.cards.e.EbonDragon.class)); - cards.add(new SetCardInfo("Elite Cat Warrior", "163a", Rarity.COMMON, EliteCatWarrior.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elite Cat Warrior", "163b", Rarity.COMMON, EliteCatWarrior.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elite Cat Warrior", "163a", Rarity.COMMON, mage.cards.e.EliteCatWarrior.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elite Cat Warrior", "163b", Rarity.COMMON, mage.cards.e.EliteCatWarrior.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Elven Cache", 164, Rarity.COMMON, mage.cards.e.ElvenCache.class)); cards.add(new SetCardInfo("Elvish Ranger", 165, Rarity.COMMON, mage.cards.e.ElvishRanger.class)); cards.add(new SetCardInfo("Endless Cockroaches", 92, Rarity.RARE, mage.cards.e.EndlessCockroaches.class)); @@ -244,8 +240,8 @@ public final class Portal extends ExpansionSet { cards.add(new SetCardInfo("Volcanic Hammer", 154, Rarity.COMMON, mage.cards.v.VolcanicHammer.class)); cards.add(new SetCardInfo("Wall of Granite", 155, Rarity.UNCOMMON, mage.cards.w.WallOfGranite.class)); cards.add(new SetCardInfo("Wall of Swords", 37, Rarity.UNCOMMON, mage.cards.w.WallOfSwords.class)); - cards.add(new SetCardInfo("Warrior's Charge", "38a", Rarity.COMMON, WarriorsCharge.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Warrior's Charge", "38b", Rarity.COMMON, WarriorsCharge.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Warrior's Charge", "38a", Rarity.COMMON, mage.cards.w.WarriorsCharge.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Warrior's Charge", "38b", Rarity.COMMON, mage.cards.w.WarriorsCharge.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Whiptail Wurm", 192, Rarity.UNCOMMON, mage.cards.w.WhiptailWurm.class)); cards.add(new SetCardInfo("Wicked Pact", 117, Rarity.RARE, mage.cards.w.WickedPact.class)); cards.add(new SetCardInfo("Willow Dryad", 193, Rarity.COMMON, mage.cards.w.WillowDryad.class)); @@ -256,4 +252,4 @@ public final class Portal extends ExpansionSet { cards.add(new SetCardInfo("Wood Elves", 195, Rarity.RARE, mage.cards.w.WoodElves.class)); cards.add(new SetCardInfo("Wrath of God", 39, Rarity.RARE, mage.cards.w.WrathOfGod.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/SeventhEdition.java b/Mage.Sets/src/mage/sets/SeventhEdition.java index 20232d82bb..bcb68617e3 100644 --- a/Mage.Sets/src/mage/sets/SeventhEdition.java +++ b/Mage.Sets/src/mage/sets/SeventhEdition.java @@ -2,13 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.g.GoblinWarDrums; -import mage.cards.s.StormShaman; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class SeventhEdition extends ExpansionSet { @@ -27,6 +24,7 @@ public final class SeventhEdition extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abyssal Horror", 115, Rarity.RARE, mage.cards.a.AbyssalHorror.class)); cards.add(new SetCardInfo("Abyssal Specter", 116, Rarity.UNCOMMON, mage.cards.a.AbyssalSpecter.class)); cards.add(new SetCardInfo("Adarkar Wastes", 325, Rarity.RARE, mage.cards.a.AdarkarWastes.class)); @@ -151,7 +149,7 @@ public final class SeventhEdition extends ExpansionSet { cards.add(new SetCardInfo("Goblin Matron", 191, Rarity.UNCOMMON, mage.cards.g.GoblinMatron.class)); cards.add(new SetCardInfo("Goblin Raider", 192, Rarity.COMMON, mage.cards.g.GoblinRaider.class)); cards.add(new SetCardInfo("Goblin Spelunkers", 193, Rarity.COMMON, mage.cards.g.GoblinSpelunkers.class)); - cards.add(new SetCardInfo("Goblin War Drums", 194, Rarity.UNCOMMON, GoblinWarDrums.class)); + cards.add(new SetCardInfo("Goblin War Drums", 194, Rarity.UNCOMMON, mage.cards.g.GoblinWarDrums.class)); cards.add(new SetCardInfo("Gorilla Chieftain", 250, Rarity.COMMON, mage.cards.g.GorillaChieftain.class)); cards.add(new SetCardInfo("Grafted Skullcap", 298, Rarity.RARE, mage.cards.g.GraftedSkullcap.class)); cards.add(new SetCardInfo("Granite Grip", 195, Rarity.COMMON, mage.cards.g.GraniteGrip.class)); @@ -318,7 +316,7 @@ public final class SeventhEdition extends ExpansionSet { cards.add(new SetCardInfo("Stone Rain", 221, Rarity.COMMON, mage.cards.s.StoneRain.class)); cards.add(new SetCardInfo("Storm Cauldron", 320, Rarity.RARE, mage.cards.s.StormCauldron.class)); cards.add(new SetCardInfo("Storm Crow", 100, Rarity.COMMON, mage.cards.s.StormCrow.class)); - cards.add(new SetCardInfo("Storm Shaman", 222, Rarity.UNCOMMON, StormShaman.class)); + cards.add(new SetCardInfo("Storm Shaman", 222, Rarity.UNCOMMON, mage.cards.s.StormShaman.class)); cards.add(new SetCardInfo("Strands of Night", 165, Rarity.UNCOMMON, mage.cards.s.StrandsOfNight.class)); cards.add(new SetCardInfo("Stream of Life", 272, Rarity.COMMON, mage.cards.s.StreamOfLife.class)); cards.add(new SetCardInfo("Stronghold Assassin", 166, Rarity.RARE, mage.cards.s.StrongholdAssassin.class)); @@ -378,4 +376,4 @@ public final class SeventhEdition extends ExpansionSet { cards.add(new SetCardInfo("Yavimaya Enchantress", 285, Rarity.UNCOMMON, mage.cards.y.YavimayaEnchantress.class)); cards.add(new SetCardInfo("Yawgmoth's Edict", 171, Rarity.UNCOMMON, mage.cards.y.YawgmothsEdict.class)); } -} +} \ No newline at end of file From c41c6e1fe9c4e930b8a6bddf89a3013d0d83b0a4 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 3 Oct 2018 13:44:01 +0200 Subject: [PATCH 014/167] Fixed a problem with casting split cards from non hand zone. Added some generic cast from non hand zone effects and started replacing card specific effects by the generic ones (fixes #5356 and fixes #4493). --- .../mage/cards/a/AbandonedSarcophagus.java | 54 +++--------- .../src/mage/cards/a/AbbotOfKeralKeep.java | 4 +- Mage.Sets/src/mage/cards/a/ActOnImpulse.java | 35 +------- Mage.Sets/src/mage/cards/a/AerialCaravan.java | 35 +------- Mage.Sets/src/mage/cards/a/ApexOfPower.java | 33 +------- .../src/mage/cards/c/ChandraPyromaster.java | 54 ++---------- .../src/mage/cards/c/CommuneWithLava.java | 3 +- .../src/mage/cards/c/CunningAbduction.java | 45 ++-------- Mage.Sets/src/mage/cards/d/DarkDecision.java | 39 +-------- .../src/mage/cards/d/DarkDwellerOracle.java | 38 ++------- .../src/mage/cards/d/DaxosOfMeletis.java | 14 ++-- Mage.Sets/src/mage/cards/d/DeadMansChest.java | 9 +- .../src/mage/cards/d/DireFleetDaredevil.java | 45 ++-------- Mage.Sets/src/mage/cards/d/DreamPillager.java | 45 +++------- Mage.Sets/src/mage/cards/e/ElkinLair.java | 8 +- .../src/mage/cards/m/MissionBriefing.java | 34 +------- .../mage/cards/n/NarsetEnlightenedMaster.java | 6 +- .../asthough/PlayFromNonHandZoneTest.java | 7 +- .../abilities/effects/ContinuousEffects.java | 23 ++++-- .../effects/common/AttachEffect.java | 5 +- .../PlayFromNotOwnHandZoneAllEffect.java | 74 +++++++++++++++++ .../PlayFromNotOwnHandZoneTargetEffect.java | 82 +++++++++++++++++++ .../abilities/keyword/AftermathAbility.java | 21 +++-- .../main/java/mage/players/PlayerImpl.java | 61 +++++++------- .../target/targetpointer/FixedTarget.java | 6 ++ 25 files changed, 304 insertions(+), 476 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/asthought/PlayFromNotOwnHandZoneAllEffect.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/asthought/PlayFromNotOwnHandZoneTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java b/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java index 5d44aa8dd6..81a7e42baf 100644 --- a/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java +++ b/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java @@ -1,4 +1,3 @@ - package mage.cards.a; import java.util.HashMap; @@ -7,18 +6,18 @@ import java.util.Map.Entry; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneAllEffect; import mage.abilities.keyword.CyclingAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; -import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.TargetController; import mage.constants.WatcherScope; import mage.constants.Zone; import mage.filter.FilterCard; @@ -42,7 +41,14 @@ public final class AbandonedSarcophagus extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // You may cast nonland cards with cycling from your graveyard. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AbandonedSarcophagusCastFromGraveyardEffect())); + FilterCard filter = new FilterCard("nonland cards with cycling"); + filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + filter.add(new AbilityPredicate(CyclingAbility.class)); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new PlayFromNotOwnHandZoneAllEffect(filter, + Zone.GRAVEYARD, true, TargetController.YOU, Duration.WhileOnBattlefield) + .setText("You may cast nonland cards with cycling from your graveyard")) + ); // If a card with cycling would be put into your graveyard from anywhere and it wasn't cycled, exile it instead. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AbandonedSarcophagusReplacementEffect()), new AbandonedSarcophagusWatcher()); @@ -59,46 +65,6 @@ public final class AbandonedSarcophagus extends CardImpl { } } -class AbandonedSarcophagusCastFromGraveyardEffect extends AsThoughEffectImpl { - - private static final FilterCard filter = new FilterCard("nonland cards with cycling"); - - static { - filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); - filter.add(new AbilityPredicate(CyclingAbility.class)); - } - - AbandonedSarcophagusCastFromGraveyardEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "You may cast nonland cards with cycling from your graveyard"; - } - - AbandonedSarcophagusCastFromGraveyardEffect(final AbandonedSarcophagusCastFromGraveyardEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public AbandonedSarcophagusCastFromGraveyardEffect copy() { - return new AbandonedSarcophagusCastFromGraveyardEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - Card card = game.getCard(objectId); - if (card != null) { - return (affectedControllerId.equals(source.getControllerId()) - && filter.match(card, game) - && game.getState().getZone(card.getId()) == Zone.GRAVEYARD); - } - return false; - } -} - class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl { boolean cardHasCycling; diff --git a/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java b/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java index c8a371940d..0d85e9cf3c 100644 --- a/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java +++ b/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java @@ -1,4 +1,3 @@ - package mage.cards.a; import java.util.UUID; @@ -8,6 +7,7 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.keyword.ProwessAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -75,7 +75,7 @@ class AbbotOfKeralKeepExileEffect extends OneShotEffect { if (card != null) { String exileName = sourcePermanent.getIdName() + " "; controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); - ContinuousEffect effect = new AbbotOfKeralKeepCastFromExileEffect(); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Duration.EndOfTurn); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); game.addEffect(effect, source); } diff --git a/Mage.Sets/src/mage/cards/a/ActOnImpulse.java b/Mage.Sets/src/mage/cards/a/ActOnImpulse.java index 11bc0aed5b..a2f44ab166 100644 --- a/Mage.Sets/src/mage/cards/a/ActOnImpulse.java +++ b/Mage.Sets/src/mage/cards/a/ActOnImpulse.java @@ -1,4 +1,3 @@ - package mage.cards.a; import java.util.HashSet; @@ -6,9 +5,9 @@ import java.util.Set; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -44,7 +43,7 @@ class ActOnImpulseExileEffect extends OneShotEffect { public ActOnImpulseExileEffect() { super(Outcome.Benefit); - this.staticText = "Exile the top three cards of your library. Until end of turn, you may play cards exiled this way."; + this.staticText = "Exile the top three cards of your library. Until end of turn, you may play cards exiled this way"; } public ActOnImpulseExileEffect(final ActOnImpulseExileEffect effect) { @@ -71,7 +70,7 @@ class ActOnImpulseExileEffect extends OneShotEffect { } } if (!cards.isEmpty()) { - ContinuousEffect effect = new ActOnImpulseMayPlayExiledEffect(); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); effect.setTargetPointer(new FixedTargets(cards, game)); game.addEffect(effect, source); } @@ -82,31 +81,3 @@ class ActOnImpulseExileEffect extends OneShotEffect { } } - -class ActOnImpulseMayPlayExiledEffect extends AsThoughEffectImpl { - - public ActOnImpulseMayPlayExiledEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - } - - public ActOnImpulseMayPlayExiledEffect(final ActOnImpulseMayPlayExiledEffect effect) { - super(effect); - } - - @Override - public ActOnImpulseMayPlayExiledEffect copy() { - return new ActOnImpulseMayPlayExiledEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return affectedControllerId.equals(source.getControllerId()) - && getTargetPointer().getTargets(game, source).contains(objectId); - } - -} diff --git a/Mage.Sets/src/mage/cards/a/AerialCaravan.java b/Mage.Sets/src/mage/cards/a/AerialCaravan.java index 933595fcd9..27524c47b4 100644 --- a/Mage.Sets/src/mage/cards/a/AerialCaravan.java +++ b/Mage.Sets/src/mage/cards/a/AerialCaravan.java @@ -1,4 +1,3 @@ - package mage.cards.a; import java.util.UUID; @@ -6,18 +5,18 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.SubType; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Library; @@ -81,7 +80,7 @@ class AerialCaravanExileEffect extends OneShotEffect { if (card != null) { String exileName = sourcePermanent.getIdName() + " "; controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); - ContinuousEffect effect = new AerialCaravanCastFromExileEffect(); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); game.addEffect(effect, source); } @@ -90,31 +89,3 @@ class AerialCaravanExileEffect extends OneShotEffect { return false; } } - -class AerialCaravanCastFromExileEffect extends AsThoughEffectImpl { - - public AerialCaravanCastFromExileEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may play the card from exile"; - } - - public AerialCaravanCastFromExileEffect(final AerialCaravanCastFromExileEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public AerialCaravanCastFromExileEffect copy() { - return new AerialCaravanCastFromExileEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.isControlledBy(affectedControllerId) - && objectId.equals(getTargetPointer().getFirst(game, source)); - } -} diff --git a/Mage.Sets/src/mage/cards/a/ApexOfPower.java b/Mage.Sets/src/mage/cards/a/ApexOfPower.java index 7cedb5425b..edf7670988 100644 --- a/Mage.Sets/src/mage/cards/a/ApexOfPower.java +++ b/Mage.Sets/src/mage/cards/a/ApexOfPower.java @@ -4,14 +4,13 @@ import java.util.Set; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; @@ -79,7 +78,7 @@ class ApexOfPowerSpellEffect extends OneShotEffect { if (card.isLand()) { continue; } - ContinuousEffect effect = new ApexOfPowerCastFromExileEffect(); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); game.addEffect(effect, source); } @@ -87,34 +86,6 @@ class ApexOfPowerSpellEffect extends OneShotEffect { } } -class ApexOfPowerCastFromExileEffect extends AsThoughEffectImpl { - - public ApexOfPowerCastFromExileEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may play the card from exile"; - } - - public ApexOfPowerCastFromExileEffect(final ApexOfPowerCastFromExileEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public ApexOfPowerCastFromExileEffect copy() { - return new ApexOfPowerCastFromExileEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.isControlledBy(affectedControllerId) - && objectId.equals(getTargetPointer().getFirst(game, source)); - } -} - class ApexOfPowerManaEffect extends OneShotEffect { public ApexOfPowerManaEffect() { diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java index bccba20571..027213fdb3 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java @@ -1,4 +1,3 @@ - package mage.cards.c; import java.util.HashSet; @@ -9,9 +8,9 @@ import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.effects.common.combat.CantBlockTargetEffect; import mage.cards.*; import mage.constants.*; @@ -20,7 +19,6 @@ import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.stack.StackObject; -import mage.players.Library; import mage.players.Player; import mage.target.Target; import mage.target.TargetCard; @@ -177,12 +175,13 @@ class ChandraPyromasterEffect2 extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); - if (controller != null && sourceObject != null && controller.getLibrary().hasCards()) { - Library library = controller.getLibrary(); - Card card = library.getFromTop(game); + if (controller != null && sourceObject != null) { + Card card = controller.getLibrary().getFromTop(game); if (card != null) { - controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName() + " ", source.getSourceId(), game, Zone.LIBRARY, true); - game.addEffect(new ChandraPyromasterPlayEffect(new MageObjectReference(card, game)), source); + controller.moveCards(card, Zone.EXILED, source, game); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(card, game)); + game.addEffect(effect, source); } return true; } @@ -190,45 +189,6 @@ class ChandraPyromasterEffect2 extends OneShotEffect { } } -class ChandraPyromasterPlayEffect extends AsThoughEffectImpl { - - private final MageObjectReference objectReference; - - public ChandraPyromasterPlayEffect(MageObjectReference objectReference) { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - this.objectReference = objectReference; - staticText = "you may play that card until end of turn"; - } - - public ChandraPyromasterPlayEffect(final ChandraPyromasterPlayEffect effect) { - super(effect); - this.objectReference = effect.objectReference; - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public ChandraPyromasterPlayEffect copy() { - return new ChandraPyromasterPlayEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (objectReference.refersTo(objectId, game) && affectedControllerId.equals(source.getControllerId())) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - return true; - } else { - discard(); - } - } - return false; - } -} - class ChandraPyromasterEffect3 extends OneShotEffect { public ChandraPyromasterEffect3() { diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithLava.java b/Mage.Sets/src/mage/cards/c/CommuneWithLava.java index e38056a591..08cf2112e7 100644 --- a/Mage.Sets/src/mage/cards/c/CommuneWithLava.java +++ b/Mage.Sets/src/mage/cards/c/CommuneWithLava.java @@ -1,4 +1,3 @@ - package mage.cards.c; import java.util.Set; @@ -23,7 +22,7 @@ import mage.util.CardUtil; public final class CommuneWithLava extends CardImpl { public CommuneWithLava(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{R}"); // Exile the top X cards of your library. Until the end of your next turn, you may play those cards. this.getSpellAbility().addEffect(new CommuneWithLavaEffect()); diff --git a/Mage.Sets/src/mage/cards/c/CunningAbduction.java b/Mage.Sets/src/mage/cards/c/CunningAbduction.java index 1bbb4ac15b..f34a14e72c 100644 --- a/Mage.Sets/src/mage/cards/c/CunningAbduction.java +++ b/Mage.Sets/src/mage/cards/c/CunningAbduction.java @@ -1,4 +1,3 @@ - package mage.cards.c; import java.util.UUID; @@ -8,6 +7,7 @@ import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -28,7 +28,7 @@ import mage.util.CardUtil; public final class CunningAbduction extends CardImpl { public CunningAbduction(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{B}"); // Target opponent reveals their hand. You choose a nonland card from that player's hand and exile it. You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell. this.getSpellAbility().addTarget(new TargetOpponent()); @@ -82,10 +82,10 @@ class CunningAbductionExileEffect extends OneShotEffect { if (card != null) { // move card to exile UUID exileId = CardUtil.getCardExileZoneId(game, source); - controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.HAND, true); + controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getIdName()); // allow to cast the card - ContinuousEffect effect = new CunningAbductionCastFromExileEffect(); - effect.setTargetPointer(new FixedTarget(card.getId())); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.Custom); + effect.setTargetPointer(new FixedTarget(card, game)); game.addEffect(effect, source); // and you may spend mana as though it were mana of any color to cast it effect = new CunningAbductionSpendAnyManaEffect(); @@ -99,41 +99,6 @@ class CunningAbductionExileEffect extends OneShotEffect { } } -class CunningAbductionCastFromExileEffect extends AsThoughEffectImpl { - - public CunningAbductionCastFromExileEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); - staticText = "You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell"; - } - - public CunningAbductionCastFromExileEffect(final CunningAbductionCastFromExileEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public CunningAbductionCastFromExileEffect copy() { - return new CunningAbductionCastFromExileEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (objectId.equals(getTargetPointer().getFirst(game, source))) { - if (affectedControllerId.equals(source.getControllerId())) { - return true; - } - } else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { - // object has moved zone so effect can be discarted - this.discard(); - } - return false; - } -} - class CunningAbductionSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { public CunningAbductionSpendAnyManaEffect() { diff --git a/Mage.Sets/src/mage/cards/d/DarkDecision.java b/Mage.Sets/src/mage/cards/d/DarkDecision.java index 880f0216af..f89c73413b 100644 --- a/Mage.Sets/src/mage/cards/d/DarkDecision.java +++ b/Mage.Sets/src/mage/cards/d/DarkDecision.java @@ -1,22 +1,20 @@ - package mage.cards.d; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.costs.common.PayLifeCost; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Zone; import mage.filter.common.FilterNonlandCard; -import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInLibrary; @@ -76,7 +74,7 @@ class DarkDecisionEffect extends OneShotEffect { Card card = game.getCard(targetId); if (card != null) { controller.moveCardsToExile(card, source, game, true, source.getSourceId(), sourceObject.getIdName()); - ContinuousEffect effect = new DarkDecisionMayPlayExiledEffect(); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); effect.setTargetPointer(new FixedTarget(card.getId(), game)); game.addEffect(effect, source); } @@ -88,34 +86,3 @@ class DarkDecisionEffect extends OneShotEffect { } } - -class DarkDecisionMayPlayExiledEffect extends AsThoughEffectImpl { - - public DarkDecisionMayPlayExiledEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - } - - public DarkDecisionMayPlayExiledEffect(final DarkDecisionMayPlayExiledEffect effect) { - super(effect); - } - - @Override - public DarkDecisionMayPlayExiledEffect copy() { - return new DarkDecisionMayPlayExiledEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (objectId.equals(getTargetPointer().getFirst(game, source)) && affectedControllerId.equals(source.getControllerId())) { - ExileZone exileZone = game.getExile().getExileZone(source.getSourceId()); - return exileZone != null && exileZone.contains(getTargetPointer().getFirst(game, source)); - } - return false; - } - -} diff --git a/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java b/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java index bef6334009..fc1d1a3426 100644 --- a/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java +++ b/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java @@ -6,17 +6,17 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.cards.Card; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; import mage.game.Game; import mage.game.permanent.Permanent; @@ -88,8 +88,8 @@ class DarkDwellerOracleExileEffect extends OneShotEffect { if (card != null) { String exileName = sourcePermanent.getIdName() + " "; controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); - ContinuousEffect effect = new DarkDwellerOracleCastFromExileEffect(); - effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(card, game)); game.addEffect(effect, source); } return true; @@ -97,31 +97,3 @@ class DarkDwellerOracleExileEffect extends OneShotEffect { return false; } } - -class DarkDwellerOracleCastFromExileEffect extends AsThoughEffectImpl { - - public DarkDwellerOracleCastFromExileEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may play the card from exile"; - } - - public DarkDwellerOracleCastFromExileEffect(final DarkDwellerOracleCastFromExileEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public DarkDwellerOracleCastFromExileEffect copy() { - return new DarkDwellerOracleCastFromExileEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.isControlledBy(affectedControllerId) - && objectId.equals(getTargetPointer().getFirst(game, source)); - } -} diff --git a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java index 0f13053b5a..87131ba9ba 100644 --- a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java +++ b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.Objects; @@ -12,6 +11,7 @@ import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -39,7 +39,7 @@ public final class DaxosOfMeletis extends CardImpl { } public DaxosOfMeletis(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); @@ -91,7 +91,7 @@ class DaxosOfMeletisEffect extends OneShotEffect { Card card = damagedPlayer.getLibrary().getFromTop(game); if (card != null) { // move card to exile - controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); + controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getIdName()); // player gains life int cmc = card.getConvertedManaCost(); if (cmc > 0) { @@ -100,10 +100,12 @@ class DaxosOfMeletisEffect extends OneShotEffect { // Add effects only if the card has a spellAbility (e.g. not for lands). if (card.getSpellAbility() != null) { // allow to cast the card - game.addEffect(new DaxosOfMeletisCastFromExileEffect(card.getId(), exileId), source); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(card, game)); + game.addEffect(effect, source); // and you may spend mana as though it were mana of any color to cast it - ContinuousEffect effect = new DaxosOfMeletisSpendAnyManaEffect(); - effect.setTargetPointer(new FixedTarget(card.getId())); + effect = new DaxosOfMeletisSpendAnyManaEffect(); + effect.setTargetPointer(new FixedTarget(card, game)); game.addEffect(effect, source); } } diff --git a/Mage.Sets/src/mage/cards/d/DeadMansChest.java b/Mage.Sets/src/mage/cards/d/DeadMansChest.java index 24c8de7bda..76a659af21 100644 --- a/Mage.Sets/src/mage/cards/d/DeadMansChest.java +++ b/Mage.Sets/src/mage/cards/d/DeadMansChest.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.Set; @@ -11,6 +10,7 @@ import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -22,6 +22,7 @@ import mage.constants.ManaType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.TargetController; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; @@ -101,11 +102,11 @@ class DeadMansChestEffect extends OneShotEffect { controller.moveCardsToExile(cards, source, game, true, source.getSourceId(), sourceObject.getLogName()); for (Card card : cards) { if (!card.isLand()) { - ContinuousEffect effect = new DeadMansChestCastFromExileEffect(); - effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.Custom); + effect.setTargetPointer(new FixedTarget(card, game)); game.addEffect(effect, source); effect = new DeadMansChestSpendManaEffect(); - effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); + effect.setTargetPointer(new FixedTarget(card, game)); game.addEffect(effect, source); } } diff --git a/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java b/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java index 72fe39f0ca..f49e33e705 100644 --- a/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java +++ b/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.Objects; @@ -11,6 +10,7 @@ import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -102,14 +102,14 @@ class DireFleetDaredevilEffect extends OneShotEffect { if (controller.moveCards(targetCard, Zone.EXILED, source, game)) { targetCard = game.getCard(targetCard.getId()); if (targetCard != null) { - ContinuousEffect effect = new DireFleetDaredevilPlayEffect(); - effect.setTargetPointer(new FixedTarget(targetCard.getId(), targetCard.getZoneChangeCounter(game))); + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(targetCard, game)); game.addEffect(effect, source); effect = new DireFleetDaredevilSpendAnyManaEffect(); - effect.setTargetPointer(new FixedTarget(targetCard.getId(), targetCard.getZoneChangeCounter(game))); + effect.setTargetPointer(new FixedTarget(targetCard, game)); game.addEffect(effect, source); effect = new DireFleetDaredevilReplacementEffect(); - effect.setTargetPointer(new FixedTarget(targetCard.getId(), targetCard.getZoneChangeCounter(game))); + effect.setTargetPointer(new FixedTarget(targetCard, game)); game.addEffect(effect, source); } @@ -121,41 +121,6 @@ class DireFleetDaredevilEffect extends OneShotEffect { } } -class DireFleetDaredevilPlayEffect extends AsThoughEffectImpl { - - public DireFleetDaredevilPlayEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may cast that card this turn"; - } - - public DireFleetDaredevilPlayEffect(final DireFleetDaredevilPlayEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public DireFleetDaredevilPlayEffect copy() { - return new DireFleetDaredevilPlayEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - UUID targetId = getTargetPointer().getFirst(game, source); - if (targetId != null) { - return targetId.equals(objectId) - && source.isControlledBy(affectedControllerId); - } else { - // the target card has changed zone meanwhile, so the effect is no longer needed - discard(); - return false; - } - } -} - class DireFleetDaredevilSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { public DireFleetDaredevilSpendAnyManaEffect() { diff --git a/Mage.Sets/src/mage/cards/d/DreamPillager.java b/Mage.Sets/src/mage/cards/d/DreamPillager.java index e0eefc81fe..67869fe511 100644 --- a/Mage.Sets/src/mage/cards/d/DreamPillager.java +++ b/Mage.Sets/src/mage/cards/d/DreamPillager.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.Set; @@ -7,21 +6,23 @@ import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.*; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; +import mage.target.targetpointer.FixedTargets; /** * @@ -30,7 +31,7 @@ import mage.target.targetpointer.FixedTarget; public final class DreamPillager extends CardImpl { public DreamPillager(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(4); this.toughness = new MageInt(4); @@ -114,13 +115,15 @@ class DreamPillagerEffect extends OneShotEffect { Set cards = controller.getLibrary().getTopCards(game, amount); if (!cards.isEmpty()) { controller.moveCards(cards, Zone.EXILED, source, game); + Cards canBeCast = new CardsImpl(); for (Card card : cards) { if (!card.isLand()) { - ContinuousEffect effect = new DreamPillagerCastFromExileEffect(); - effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); - game.addEffect(effect, source); + canBeCast.add(card); } } + ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTargets(canBeCast, game)); + game.addEffect(effect, source); } return true; } @@ -129,31 +132,3 @@ class DreamPillagerEffect extends OneShotEffect { return false; } } - -class DreamPillagerCastFromExileEffect extends AsThoughEffectImpl { - - public DreamPillagerCastFromExileEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may play the card from exile"; - } - - public DreamPillagerCastFromExileEffect(final DreamPillagerCastFromExileEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public DreamPillagerCastFromExileEffect copy() { - return new DreamPillagerCastFromExileEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.isControlledBy(affectedControllerId) - && objectId.equals(getTargetPointer().getFirst(game, source)); - } -} diff --git a/Mage.Sets/src/mage/cards/e/ElkinLair.java b/Mage.Sets/src/mage/cards/e/ElkinLair.java index 41b7287efd..8539e15b47 100644 --- a/Mage.Sets/src/mage/cards/e/ElkinLair.java +++ b/Mage.Sets/src/mage/cards/e/ElkinLair.java @@ -1,4 +1,3 @@ - package mage.cards.e; import java.util.Set; @@ -10,6 +9,7 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -20,9 +20,9 @@ import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.FilterCard; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.filter.FilterCard; import mage.players.Player; import mage.target.targetpointer.FixedTarget; import mage.util.RandomUtil; @@ -81,8 +81,8 @@ class ElkinLairUpkeepEffect extends OneShotEffect { String exileName = sourcePermanent.getIdName() + " asThoughEffectsList = getApplicableAsThoughEffects(type, game); - for (AsThoughEffect effect : asThoughEffectsList) { - Set abilities = asThoughEffectsMap.get(type).getAbility(effect.getId()); - for (Ability ability : abilities) { - if (affectedAbility == null) { - if (effect.applies(objectId, ability, controllerId, game)) { + if (!asThoughEffectsList.isEmpty()) { + UUID idToCheck; + if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof SplitCardHalf) { + idToCheck = ((SplitCardHalf) affectedAbility.getSourceObject(game)).getParentCard().getId(); + } else { + idToCheck = objectId; + } + for (AsThoughEffect effect : asThoughEffectsList) { + Set abilities = asThoughEffectsMap.get(type).getAbility(effect.getId()); + for (Ability ability : abilities) { + if (affectedAbility == null) { + if (effect.applies(idToCheck, ability, controllerId, game)) { + return new MageObjectReference(ability.getSourceObject(game), game); + } + } else if (effect.applies(idToCheck, affectedAbility, ability, game, controllerId)) { return new MageObjectReference(ability.getSourceObject(game), game); } - } else if (effect.applies(objectId, affectedAbility, ability, game, controllerId)) { - return new MageObjectReference(ability.getSourceObject(game), game); } } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/AttachEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AttachEffect.java index 989a71b1c2..11fae020f2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AttachEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/AttachEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common; import mage.abilities.Ability; @@ -39,7 +38,9 @@ public class AttachEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (sourcePermanent != null) { int zcc = game.getState().getZoneChangeCounter(sourcePermanent.getId()); - if (zcc == source.getSourceObjectZoneChangeCounter() || zcc == source.getSourceObjectZoneChangeCounter() + 1) { + if (zcc == source.getSourceObjectZoneChangeCounter() + || zcc == source.getSourceObjectZoneChangeCounter() + 1 + || zcc == source.getSourceObjectZoneChangeCounter() + 2) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent != null) { return permanent.addAttachment(source.getSourceId(), game); diff --git a/Mage/src/main/java/mage/abilities/effects/common/asthought/PlayFromNotOwnHandZoneAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/asthought/PlayFromNotOwnHandZoneAllEffect.java new file mode 100644 index 0000000000..5b3927f213 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/asthought/PlayFromNotOwnHandZoneAllEffect.java @@ -0,0 +1,74 @@ +package mage.abilities.effects.common.asthought; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.cards.Card; +import mage.constants.AsThoughEffectType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; + +/** + * + * @author LevelX2 + */ +public class PlayFromNotOwnHandZoneAllEffect extends AsThoughEffectImpl { + + private final FilterCard filter; + private final Zone fromZone; + private final boolean onlyOwnedCards; + private final TargetController allowedCaster; + + public PlayFromNotOwnHandZoneAllEffect(FilterCard filter, Zone fromZone, boolean onlyOwnedCards, TargetController allowedCaster, Duration duration) { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, duration, Outcome.Benefit); + this.filter = filter; + this.fromZone = fromZone; + this.onlyOwnedCards = onlyOwnedCards; + this.allowedCaster = allowedCaster; + } + + public PlayFromNotOwnHandZoneAllEffect(final PlayFromNotOwnHandZoneAllEffect effect) { + super(effect); + this.filter = effect.filter; + this.fromZone = effect.fromZone; + this.onlyOwnedCards = effect.onlyOwnedCards; + this.allowedCaster = effect.allowedCaster; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public PlayFromNotOwnHandZoneAllEffect copy() { + return new PlayFromNotOwnHandZoneAllEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + Card card = game.getCard(objectId); + if (card != null) { + switch (allowedCaster) { + case YOU: + if (affectedControllerId != source.getControllerId()) { + return false; + } + break; + case OPPONENT: + if (!game.getOpponents(source.getControllerId()).contains(affectedControllerId)) { + return false; + } + break; + } + return !onlyOwnedCards || card.getOwnerId().equals(source.getControllerId()) + && filter.match(card, game) + && game.getState().getZone(card.getId()).match(fromZone); + } + return false; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/asthought/PlayFromNotOwnHandZoneTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/asthought/PlayFromNotOwnHandZoneTargetEffect.java new file mode 100644 index 0000000000..ec878eb5b1 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/asthought/PlayFromNotOwnHandZoneTargetEffect.java @@ -0,0 +1,82 @@ +package mage.abilities.effects.common.asthought; + +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.constants.AsThoughEffectType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; + +/** + * + * @author LevelX2 + */ +public class PlayFromNotOwnHandZoneTargetEffect extends AsThoughEffectImpl { + + private final Zone fromZone; + private final TargetController allowedCaster; + + public PlayFromNotOwnHandZoneTargetEffect() { + this(Duration.EndOfTurn); + } + + public PlayFromNotOwnHandZoneTargetEffect(Duration duration) { + this(Zone.ALL, TargetController.YOU, duration); + } + + public PlayFromNotOwnHandZoneTargetEffect(Zone fromZone, Duration duration) { + this(fromZone, TargetController.YOU, duration); + } + + public PlayFromNotOwnHandZoneTargetEffect(Zone fromZone, TargetController allowedCaster, Duration duration) { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, duration, Outcome.Benefit); + this.fromZone = fromZone; + this.allowedCaster = allowedCaster; + } + + public PlayFromNotOwnHandZoneTargetEffect(final PlayFromNotOwnHandZoneTargetEffect effect) { + super(effect); + this.fromZone = effect.fromZone; + this.allowedCaster = effect.allowedCaster; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public PlayFromNotOwnHandZoneTargetEffect copy() { + return new PlayFromNotOwnHandZoneTargetEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + switch (allowedCaster) { + case YOU: + if (affectedControllerId != source.getControllerId()) { + return false; + } + break; + case OPPONENT: + if (!game.getOpponents(source.getControllerId()).contains(affectedControllerId)) { + return false; + } + break; + case ANY: + break; + } + List targets = getTargetPointer().getTargets(game, source); + if (targets.isEmpty()) { + this.discard(); + return false; + } + return targets.contains(objectId) + && affectedControllerId.equals(source.getControllerId()) + && game.getState().getZone(objectId).match(fromZone); + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/AftermathAbility.java b/Mage/src/main/java/mage/abilities/keyword/AftermathAbility.java index d661dea215..bb9c97f3cc 100644 --- a/Mage/src/main/java/mage/abilities/keyword/AftermathAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/AftermathAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.keyword; import java.util.UUID; @@ -68,16 +67,19 @@ class AftermathCastFromGraveyard extends AsThoughEffectImpl { } @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (objectId.equals(source.getSourceId()) + public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID affectedControllerId) { + if (affectedAbility != null && affectedAbility.getSourceId().equals(source.getSourceId()) && affectedControllerId.equals(source.getControllerId())) { - Card card = game.getCard(source.getSourceId()); - if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { - return true; - } + return game.getState().getZone(objectId).equals(Zone.GRAVEYARD); } return false; } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + return false; + } + } class AftermathCantCastFromHand extends ContinuousRuleModifyingEffectImpl { @@ -168,17 +170,14 @@ class AftermathExileAsResolvesFromGraveyard extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - UUID sourceId = source.getSourceId(); Card sourceCard = game.getCard(source.getSourceId()); if (sourceCard instanceof SplitCardHalf) { sourceCard = ((SplitCardHalf) sourceCard).getParentCard(); - sourceId = sourceCard.getId(); } - if (sourceCard != null) { Player player = game.getPlayer(sourceCard.getOwnerId()); if (player != null) { - return player.moveCardToExileWithInfo(sourceCard, null, "", sourceId, game, ((ZoneChangeEvent) event).getFromZone(), true); + return player.moveCards(sourceCard, Zone.EXILED, source, game); } } return false; diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 2a0560ecc4..2659dfd145 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1,5 +1,9 @@ package mage.players; +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Map.Entry; import mage.ConditionalMana; import mage.MageObject; import mage.MageObjectReference; @@ -68,11 +72,6 @@ import mage.util.GameLog; import mage.util.RandomUtil; import org.apache.log4j.Logger; -import java.io.Serializable; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.Map.Entry; - public abstract class PlayerImpl implements Player, Serializable { private static final Logger logger = Logger.getLogger(PlayerImpl.class); @@ -2563,7 +2562,7 @@ public abstract class PlayerImpl implements Player, Serializable { /** * @param game * @param appliedEffects - * @param numSides Number of sides the dice has + * @param numSides Number of sides the dice has * @return the number that the player rolled */ @Override @@ -2597,10 +2596,10 @@ public abstract class PlayerImpl implements Player, Serializable { /** * @param game * @param appliedEffects - * @param numberChaosSides The number of chaos sides the planar die - * currently has (normally 1 but can be 5) + * @param numberChaosSides The number of chaos sides the planar die + * currently has (normally 1 but can be 5) * @param numberPlanarSides The number of chaos sides the planar die - * currently has (normally 1) + * currently has (normally 1) * @return the outcome that the player rolled. Either ChaosRoll, PlanarRoll * or NilRoll */ @@ -2757,7 +2756,7 @@ public abstract class PlayerImpl implements Player, Serializable { /** * @param ability - * @param available if null, it won't be checked if enough mana is available + * @param available if null, it won't be checked if enough mana is available * @param sourceObject * @param game * @return @@ -2927,7 +2926,7 @@ public abstract class PlayerImpl implements Player, Serializable { } private void getPlayableFromGraveyardCard(Game game, Card card, Abilities candidateAbilities, ManaOptions availableMana, List output) { - MageObjectReference permittingObject = game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game); + MageObjectReference permittingObject = game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, card.getSpellAbility(), this.getId(), game); for (ActivatedAbility ability : candidateAbilities.getActivatedAbilities(Zone.ALL)) { boolean possible = false; if (ability.getZone().match(Zone.GRAVEYARD)) { @@ -3033,7 +3032,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (player != null) { if (/*player.isTopCardRevealed() &&*/player.getLibrary().hasCards()) { Card card = player.getLibrary().getFromTop(game); - if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, getId(), game)) { + if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, card.getSpellAbility(), getId(), game)) { for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) { if (ability instanceof SpellAbility || ability instanceof PlayLandAbility) { playable.add(ability); @@ -3309,7 +3308,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean canPaySacrificeCost(Permanent permanent, UUID sourceId, - UUID controllerId, Game game + UUID controllerId, Game game ) { return sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, sourceId, controllerId, game); } @@ -3457,8 +3456,8 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCards(Card card, Zone toZone, - Ability source, Game game, - boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects + Ability source, Game game, + boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects ) { Set cardList = new HashSet<>(); if (card != null) { @@ -3469,22 +3468,22 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCards(Cards cards, Zone toZone, - Ability source, Game game + Ability source, Game game ) { return moveCards(cards.getCards(game), toZone, source, game); } @Override public boolean moveCards(Set cards, Zone toZone, - Ability source, Game game + Ability source, Game game ) { return moveCards(cards, toZone, source, game, false, false, false, null); } @Override public boolean moveCards(Set cards, Zone toZone, - Ability source, Game game, - boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects + Ability source, Game game, + boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects ) { if (cards.isEmpty()) { return true; @@ -3570,8 +3569,8 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCardsToExile(Card card, Ability source, - Game game, boolean withName, UUID exileId, - String exileZoneName + Game game, boolean withName, UUID exileId, + String exileZoneName ) { Set cards = new HashSet<>(); cards.add(card); @@ -3580,8 +3579,8 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCardsToExile(Set cards, Ability source, - Game game, boolean withName, UUID exileId, - String exileZoneName + Game game, boolean withName, UUID exileId, + String exileZoneName ) { if (cards.isEmpty()) { return true; @@ -3596,14 +3595,14 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCardToHandWithInfo(Card card, UUID sourceId, - Game game + Game game ) { return this.moveCardToHandWithInfo(card, sourceId, game, true); } @Override public boolean moveCardToHandWithInfo(Card card, UUID sourceId, - Game game, boolean withName + Game game, boolean withName ) { boolean result = false; Zone fromZone = game.getState().getZone(card.getId()); @@ -3628,7 +3627,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public Set moveCardsToGraveyardWithInfo(Set allCards, Ability source, - Game game, Zone fromZone + Game game, Zone fromZone ) { UUID sourceId = source == null ? null : source.getSourceId(); Set movedCards = new LinkedHashSet<>(); @@ -3636,7 +3635,7 @@ public abstract class PlayerImpl implements Player, Serializable { // identify cards from one owner Cards cards = new CardsImpl(); UUID ownerId = null; - for (Iterator it = allCards.iterator(); it.hasNext(); ) { + for (Iterator it = allCards.iterator(); it.hasNext();) { Card card = it.next(); if (cards.isEmpty()) { ownerId = card.getOwnerId(); @@ -3697,7 +3696,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, - Game game, Zone fromZone + Game game, Zone fromZone ) { if (card == null) { return false; @@ -3726,8 +3725,8 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, - Game game, Zone fromZone, - boolean toTop, boolean withName + Game game, Zone fromZone, + boolean toTop, boolean withName ) { if (card == null) { return false; @@ -3761,7 +3760,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId, - Game game, Zone fromZone, boolean withName) { + Game game, Zone fromZone, boolean withName) { if (card == null) { return false; } diff --git a/Mage/src/main/java/mage/target/targetpointer/FixedTarget.java b/Mage/src/main/java/mage/target/targetpointer/FixedTarget.java index c931962322..c8a14e5c27 100644 --- a/Mage/src/main/java/mage/target/targetpointer/FixedTarget.java +++ b/Mage/src/main/java/mage/target/targetpointer/FixedTarget.java @@ -21,6 +21,12 @@ public class FixedTarget implements TargetPointer { this.initialized = false; } + public FixedTarget(Card card, Game game) { + this.targetId = card.getId(); + this.zoneChangeCounter = card.getZoneChangeCounter(game); + this.initialized = true; + } + public FixedTarget(Permanent permanent, Game game) { this.targetId = permanent.getId(); this.zoneChangeCounter = permanent.getZoneChangeCounter(game); From 69546c82ce3a50aceb83f1829da03e887e074b57 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 20:32:58 +0400 Subject: [PATCH 015/167] * Added missing images for WPN and Gateway Promos (GRC) set in scryfall source; --- .../card/dl/sources/ScryfallImageSource.java | 84 +++++++++++++++- .../src/mage/sets/WPNAndGatewayPromos.java | 95 +++++++++++++++++++ Mage.Sets/src/mage/sets/WPNGateway.java | 93 ------------------ .../src/main/java/mage/verify/MtgJson.java | 18 +++- Utils/known-sets.txt | 2 +- 5 files changed, 190 insertions(+), 102 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/WPNAndGatewayPromos.java delete mode 100644 Mage.Sets/src/mage/sets/WPNGateway.java diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 294d660503..096768dc34 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -238,6 +238,7 @@ public enum ScryfallImageSource implements CardImageSource { supportedSets.add("EURO"); supportedSets.add("GPX"); supportedSets.add("ATH"); + supportedSets.add("GRC"); } @Override @@ -254,9 +255,18 @@ public enum ScryfallImageSource implements CardImageSource { // direct links to images (non localization) if (baseUrl == null) { - String linkCode = card.getSet() + "/" + card.getName(); - if (directDownloadLinks.containsKey(linkCode)) { - baseUrl = directDownloadLinks.get(linkCode); + + // set/card/number + String linkCode1 = card.getSet() + "/" + card.getName() + "/" + card.getCollectorId(); + if (directDownloadLinks.containsKey(linkCode1)) { + baseUrl = directDownloadLinks.get(linkCode1); + alternativeUrl = null; + } + + // set/card + String linkCode2 = card.getSet() + "/" + card.getName(); + if (directDownloadLinks.containsKey(linkCode2)) { + baseUrl = directDownloadLinks.get(linkCode2); alternativeUrl = null; } } @@ -377,6 +387,74 @@ public enum ScryfallImageSource implements CardImageSource { put("DPAP/Soul of Ravnica", "https://img.scryfall.com/cards/large/en/pdp14/1.jpg"); put("DPAP/Soul of Zendikar", "https://img.scryfall.com/cards/large/en/pdp14/2.jpg"); + // Gateway Promos -- xmage uses one set (GRC), but scryfall store it by years + // 2006 - https://scryfall.com/sets/pgtw + put("GRC/Fiery Temper", "https://img.scryfall.com/cards/large/en/pgtw/3.jpg"); + put("GRC/Icatian Javelineers", "https://img.scryfall.com/cards/large/en/pgtw/2.jpg"); + put("GRC/Wood Elves", "https://img.scryfall.com/cards/large/en/pgtw/1.jpg"); + // 2007 - https://scryfall.com/sets/pg07 + put("GRC/Boomerang", "https://img.scryfall.com/cards/large/en/pg07/4.jpg"); + put("GRC/Calciderm", "https://img.scryfall.com/cards/large/en/pg07/5.jpg"); + put("GRC/Dauntless Dourbark", "https://img.scryfall.com/cards/large/en/pg07/12.jpg"); + put("GRC/Llanowar Elves", "https://img.scryfall.com/cards/large/en/pg07/9.jpg"); + put("GRC/Mind Stone", "https://img.scryfall.com/cards/large/en/pg07/11.jpg"); + put("GRC/Mogg Fanatic", "https://img.scryfall.com/cards/large/en/pg07/10.jpg"); + put("GRC/Reckless Wurm", "https://img.scryfall.com/cards/large/en/pg07/6.jpg"); + put("GRC/Yixlid Jailer", "https://img.scryfall.com/cards/large/en/pg07/7.jpg"); + put("GRC/Zoetic Cavern", "https://img.scryfall.com/cards/large/en/pg07/8.jpg"); + // 2008a - https://scryfall.com/sets/pg08 + put("GRC/Boggart Ram-Gang", "https://img.scryfall.com/cards/large/en/pg08/17.jpg"); + put("GRC/Cenn's Tactician", "https://img.scryfall.com/cards/large/en/pg08/14.jpg"); + put("GRC/Duergar Hedge-Mage", "https://img.scryfall.com/cards/large/en/pg08/19.jpg"); + put("GRC/Gravedigger", "https://img.scryfall.com/cards/large/en/pg08/16.jpg"); + put("GRC/Lava Axe", "https://img.scryfall.com/cards/large/en/pg08/13.jpg"); + put("GRC/Oona's Blackguard", "https://img.scryfall.com/cards/large/en/pg08/15.jpg"); + put("GRC/Selkie Hedge-Mage", "https://img.scryfall.com/cards/large/en/pg08/20.jpg"); + put("GRC/Wilt-Leaf Cavaliers", "https://img.scryfall.com/cards/large/en/pg08/18.jpg"); + + // Wizards Play Network Promos -- xmage uses one set (GRC), but scryfall store it by years + // 2008b - https://scryfall.com/sets/pwpn + put("GRC/Sprouting Thrinax", "https://img.scryfall.com/cards/large/en/pwpn/21.jpg"); + put("GRC/Woolly Thoctar", "https://img.scryfall.com/cards/large/en/pwpn/22.jpg"); + // 2009 - https://scryfall.com/sets/pwp09 + put("GRC/Hellspark Elemental", "https://img.scryfall.com/cards/large/en/pwp09/25.jpg"); + put("GRC/Kor Duelist", "https://img.scryfall.com/cards/large/en/pwp09/32.jpg"); + put("GRC/Marisi's Twinclaws", "https://img.scryfall.com/cards/large/en/pwp09/26.jpg"); + put("GRC/Mind Control", "https://img.scryfall.com/cards/large/en/pwp09/30.jpg"); + put("GRC/Path to Exile", "https://img.scryfall.com/cards/large/en/pwp09/24.jpg"); + put("GRC/Rise from the Grave", "https://img.scryfall.com/cards/large/en/pwp09/31.jpg"); + put("GRC/Slave of Bolas", "https://img.scryfall.com/cards/large/en/pwp09/27.jpg"); + put("GRC/Vampire Nighthawk", "https://img.scryfall.com/cards/large/en/pwp09/33.jpg"); + // 2010 - https://scryfall.com/sets/pwp10 + put("GRC/Kor Firewalker", "https://img.scryfall.com/cards/large/en/pwp10/36.jpg"); + put("GRC/Leatherback Baloth", "https://img.scryfall.com/cards/large/en/pwp10/37.jpg"); + put("GRC/Syphon Mind", "https://img.scryfall.com/cards/large/en/pwp10/40.jpg"); + put("GRC/Pathrazer of Ulamog", "https://img.scryfall.com/cards/large/en/pwp10/46.jpg"); + put("GRC/Curse of Wizardry", "https://img.scryfall.com/cards/large/en/pwp10/47.jpg"); + put("GRC/Fling/50", "https://img.scryfall.com/cards/large/en/pwp10/50.jpg"); // same card but different year + put("GRC/Sylvan Ranger/51", "https://img.scryfall.com/cards/large/en/pwp10/51.jpg"); // same card but different year + put("GRC/Plague Stinger", "https://img.scryfall.com/cards/large/en/pwp10/59.jpg"); + put("GRC/Golem's Heart", "https://img.scryfall.com/cards/large/en/pwp10/60.jpg"); + put("GRC/Skinrender", "https://img.scryfall.com/cards/large/en/pwp10/63.jpg"); + // 2011 - https://scryfall.com/sets/pwp11 + put("GRC/Auramancer", "https://img.scryfall.com/cards/large/en/pwp11/77.jpg"); + put("GRC/Bloodcrazed Neonate", "https://img.scryfall.com/cards/large/en/pwp11/83.jpg"); + put("GRC/Boneyard Wurm", "https://img.scryfall.com/cards/large/en/pwp11/84.jpg"); + put("GRC/Circle of Flame", "https://img.scryfall.com/cards/large/en/pwp11/78.jpg"); + put("GRC/Curse of the Bloody Tome", "https://img.scryfall.com/cards/large/en/pwp11/80.jpg"); + put("GRC/Fling/69", "https://img.scryfall.com/cards/large/en/pwp11/69.jpg"); // same card but different year + put("GRC/Master's Call", "https://img.scryfall.com/cards/large/en/pwp11/64.jpg"); + put("GRC/Maul Splicer", "https://img.scryfall.com/cards/large/en/pwp11/72.jpg"); + put("GRC/Plague Myr", "https://img.scryfall.com/cards/large/en/pwp11/65.jpg"); + put("GRC/Shrine of Burning Rage", "https://img.scryfall.com/cards/large/en/pwp11/73.jpg"); + put("GRC/Signal Pest", "https://img.scryfall.com/cards/large/en/pwp11/66.jpg"); + put("GRC/Sylvan Ranger/70", "https://img.scryfall.com/cards/large/en/pwp11/70.jpg"); // same card but different year + put("GRC/Tormented Soul", "https://img.scryfall.com/cards/large/en/pwp11/76.jpg"); + put("GRC/Vault Skirge", "https://img.scryfall.com/cards/large/en/pwp11/71.jpg"); + // 2012 - https://scryfall.com/sets/pwp12 + put("GRC/Curse of Thirst", "https://img.scryfall.com/cards/large/en/pwp12/81.jpg"); + put("GRC/Gather the Townsfolk", "https://img.scryfall.com/cards/large/en/pwp12/79.jpg"); + put("GRC/Nearheath Stalker", "https://img.scryfall.com/cards/large/en/pwp12/82.jpg"); // TODO: remove Grand Prix fix after scryfall fix image's link (that's link must be work: https://img.scryfall.com/cards/large/en/pgpx/2016b.jpg ) put("GPX/Sword of Feast and Famine", "https://img.scryfall.com/cards/large/en/pgpx/1%E2%98%85.jpg"); diff --git a/Mage.Sets/src/mage/sets/WPNAndGatewayPromos.java b/Mage.Sets/src/mage/sets/WPNAndGatewayPromos.java new file mode 100644 index 0000000000..5f5df11705 --- /dev/null +++ b/Mage.Sets/src/mage/sets/WPNAndGatewayPromos.java @@ -0,0 +1,95 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author fireshoes, JayDi85 + */ +public final class WPNAndGatewayPromos extends ExpansionSet { + + private static final WPNAndGatewayPromos instance = new WPNAndGatewayPromos(); + + public static WPNAndGatewayPromos getInstance() { + return instance; + } + + private WPNAndGatewayPromos() { + super("WPN and Gateway Promos", "GRC", ExpansionSet.buildDate(2011, 6, 17), SetType.PROMOTIONAL); + this.hasBoosters = false; + this.hasBasicLands = false; + + // one inner set for many promos by years (Gameway + Wizards Play Network promos by years) + // https://mtg.gamepedia.com/Gateway_cards + + // Gateway Promos -- xmage uses one set (GRC), but scryfall store it by years + // 2006 - https://scryfall.com/sets/pgtw + cards.add(new SetCardInfo("Fiery Temper", 3, Rarity.RARE, mage.cards.f.FieryTemper.class)); + cards.add(new SetCardInfo("Icatian Javelineers", 2, Rarity.RARE, mage.cards.i.IcatianJavelineers.class)); + cards.add(new SetCardInfo("Wood Elves", 1, Rarity.RARE, mage.cards.w.WoodElves.class)); + // 2007 - https://scryfall.com/sets/pg07 + cards.add(new SetCardInfo("Boomerang", 4, Rarity.RARE, mage.cards.b.Boomerang.class)); + cards.add(new SetCardInfo("Calciderm", 5, Rarity.RARE, mage.cards.c.Calciderm.class)); + cards.add(new SetCardInfo("Dauntless Dourbark", 12, Rarity.RARE, mage.cards.d.DauntlessDourbark.class)); + cards.add(new SetCardInfo("Llanowar Elves", 9, Rarity.RARE, mage.cards.l.LlanowarElves.class)); + cards.add(new SetCardInfo("Mind Stone", 11, Rarity.RARE, mage.cards.m.MindStone.class)); + cards.add(new SetCardInfo("Mogg Fanatic", 10, Rarity.RARE, mage.cards.m.MoggFanatic.class)); + cards.add(new SetCardInfo("Reckless Wurm", 6, Rarity.RARE, mage.cards.r.RecklessWurm.class)); + cards.add(new SetCardInfo("Yixlid Jailer", 7, Rarity.RARE, mage.cards.y.YixlidJailer.class)); + cards.add(new SetCardInfo("Zoetic Cavern", 8, Rarity.RARE, mage.cards.z.ZoeticCavern.class)); + // 2008a - https://scryfall.com/sets/pg08 + cards.add(new SetCardInfo("Boggart Ram-Gang", 17, Rarity.RARE, mage.cards.b.BoggartRamGang.class)); + cards.add(new SetCardInfo("Cenn's Tactician", 14, Rarity.RARE, mage.cards.c.CennsTactician.class)); + cards.add(new SetCardInfo("Duergar Hedge-Mage", 19, Rarity.RARE, mage.cards.d.DuergarHedgeMage.class)); + cards.add(new SetCardInfo("Gravedigger", 16, Rarity.RARE, mage.cards.g.Gravedigger.class)); + cards.add(new SetCardInfo("Lava Axe", 13, Rarity.RARE, mage.cards.l.LavaAxe.class)); + cards.add(new SetCardInfo("Oona's Blackguard", 15, Rarity.RARE, mage.cards.o.OonasBlackguard.class)); + cards.add(new SetCardInfo("Selkie Hedge-Mage", 20, Rarity.RARE, mage.cards.s.SelkieHedgeMage.class)); + cards.add(new SetCardInfo("Wilt-Leaf Cavaliers", 18, Rarity.RARE, mage.cards.w.WiltLeafCavaliers.class)); + + // Wizards Play Network Promos -- xmage uses one set (GRC), but scryfall store it by years + // 2008b - https://scryfall.com/sets/pwpn + cards.add(new SetCardInfo("Sprouting Thrinax", 21, Rarity.RARE, mage.cards.s.SproutingThrinax.class)); + cards.add(new SetCardInfo("Woolly Thoctar", 22, Rarity.RARE, mage.cards.w.WoollyThoctar.class)); + // 2009 - https://scryfall.com/sets/pwp09 + cards.add(new SetCardInfo("Hellspark Elemental", 25, Rarity.RARE, mage.cards.h.HellsparkElemental.class)); + cards.add(new SetCardInfo("Kor Duelist", 32, Rarity.RARE, mage.cards.k.KorDuelist.class)); + cards.add(new SetCardInfo("Marisi's Twinclaws", 26, Rarity.RARE, mage.cards.m.MarisisTwinclaws.class)); + cards.add(new SetCardInfo("Mind Control", 30, Rarity.RARE, mage.cards.m.MindControl.class)); + cards.add(new SetCardInfo("Path to Exile", 24, Rarity.RARE, mage.cards.p.PathToExile.class)); + cards.add(new SetCardInfo("Rise from the Grave", 31, Rarity.RARE, mage.cards.r.RiseFromTheGrave.class)); + cards.add(new SetCardInfo("Slave of Bolas", 27, Rarity.RARE, mage.cards.s.SlaveOfBolas.class)); + cards.add(new SetCardInfo("Vampire Nighthawk", 33, Rarity.RARE, mage.cards.v.VampireNighthawk.class)); + // 2010 - https://scryfall.com/sets/pwp10 + cards.add(new SetCardInfo("Curse of Wizardry", 47, Rarity.RARE, mage.cards.c.CurseOfWizardry.class)); + cards.add(new SetCardInfo("Fling", 50, Rarity.RARE, mage.cards.f.Fling.class)); + cards.add(new SetCardInfo("Golem's Heart", 60, Rarity.RARE, mage.cards.g.GolemsHeart.class)); + cards.add(new SetCardInfo("Kor Firewalker", 36, Rarity.RARE, mage.cards.k.KorFirewalker.class)); + cards.add(new SetCardInfo("Leatherback Baloth", 37, Rarity.RARE, mage.cards.l.LeatherbackBaloth.class)); + cards.add(new SetCardInfo("Pathrazer of Ulamog", 46, Rarity.RARE, mage.cards.p.PathrazerOfUlamog.class)); + cards.add(new SetCardInfo("Plague Stinger", 59, Rarity.RARE, mage.cards.p.PlagueStinger.class)); + cards.add(new SetCardInfo("Skinrender", 63, Rarity.RARE, mage.cards.s.Skinrender.class)); + cards.add(new SetCardInfo("Sylvan Ranger", 51, Rarity.RARE, mage.cards.s.SylvanRanger.class)); + cards.add(new SetCardInfo("Syphon Mind", 40, Rarity.RARE, mage.cards.s.SyphonMind.class)); + // 2011 - https://scryfall.com/sets/pwp11 + cards.add(new SetCardInfo("Auramancer", 77, Rarity.RARE, mage.cards.a.Auramancer.class)); + cards.add(new SetCardInfo("Bloodcrazed Neonate", 83, Rarity.RARE, mage.cards.b.BloodcrazedNeonate.class)); + cards.add(new SetCardInfo("Boneyard Wurm", 84, Rarity.RARE, mage.cards.b.BoneyardWurm.class)); + cards.add(new SetCardInfo("Circle of Flame", 78, Rarity.RARE, mage.cards.c.CircleOfFlame.class)); + cards.add(new SetCardInfo("Curse of the Bloody Tome", 80, Rarity.RARE, mage.cards.c.CurseOfTheBloodyTome.class)); + cards.add(new SetCardInfo("Fling", 69, Rarity.RARE, mage.cards.f.Fling.class)); + cards.add(new SetCardInfo("Master's Call", 64, Rarity.RARE, mage.cards.m.MastersCall.class)); + cards.add(new SetCardInfo("Maul Splicer", 72, Rarity.RARE, mage.cards.m.MaulSplicer.class)); + cards.add(new SetCardInfo("Plague Myr", 65, Rarity.RARE, mage.cards.p.PlagueMyr.class)); + cards.add(new SetCardInfo("Shrine of Burning Rage", 73, Rarity.RARE, mage.cards.s.ShrineOfBurningRage.class)); + cards.add(new SetCardInfo("Signal Pest", 66, Rarity.RARE, mage.cards.s.SignalPest.class)); + cards.add(new SetCardInfo("Sylvan Ranger", 70, Rarity.RARE, mage.cards.s.SylvanRanger.class)); + cards.add(new SetCardInfo("Tormented Soul", 76, Rarity.RARE, mage.cards.t.TormentedSoul.class)); + cards.add(new SetCardInfo("Vault Skirge", 71, Rarity.RARE, mage.cards.v.VaultSkirge.class)); + // 2012 - https://scryfall.com/sets/pwp12 + cards.add(new SetCardInfo("Curse of Thirst", 81, Rarity.RARE, mage.cards.c.CurseOfThirst.class)); + cards.add(new SetCardInfo("Gather the Townsfolk", 79, Rarity.RARE, mage.cards.g.GatherTheTownsfolk.class)); + cards.add(new SetCardInfo("Nearheath Stalker", 82, Rarity.RARE, mage.cards.n.NearheathStalker.class)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/WPNGateway.java b/Mage.Sets/src/mage/sets/WPNGateway.java deleted file mode 100644 index ea7ec76c72..0000000000 --- a/Mage.Sets/src/mage/sets/WPNGateway.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.cards.i.IcatianJavelineers; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author fireshoes - */ -public final class WPNGateway extends ExpansionSet { - - private static final WPNGateway instance = new WPNGateway(); - - public static WPNGateway getInstance() { - return instance; - } - - private WPNGateway() { - super("WPN Gateway", "GRC", ExpansionSet.buildDate(2011, 6, 17), SetType.PROMOTIONAL); - this.hasBoosters = false; - this.hasBasicLands = false; - cards.add(new SetCardInfo("Auramancer", 77, Rarity.SPECIAL, mage.cards.a.Auramancer.class)); - cards.add(new SetCardInfo("Bloodcrazed Neonate", 83, Rarity.SPECIAL, mage.cards.b.BloodcrazedNeonate.class)); - cards.add(new SetCardInfo("Boggart Ram-Gang", 17, Rarity.SPECIAL, mage.cards.b.BoggartRamGang.class)); - cards.add(new SetCardInfo("Boneyard Wurm", 84, Rarity.SPECIAL, mage.cards.b.BoneyardWurm.class)); - cards.add(new SetCardInfo("Boomerang", 4, Rarity.SPECIAL, mage.cards.b.Boomerang.class)); - cards.add(new SetCardInfo("Calciderm", 5, Rarity.SPECIAL, mage.cards.c.Calciderm.class)); - cards.add(new SetCardInfo("Cenn's Tactician", 14, Rarity.SPECIAL, mage.cards.c.CennsTactician.class)); - cards.add(new SetCardInfo("Circle of Flame", 78, Rarity.SPECIAL, mage.cards.c.CircleOfFlame.class)); - cards.add(new SetCardInfo("Curse of the Bloody Tome", 80, Rarity.SPECIAL, mage.cards.c.CurseOfTheBloodyTome.class)); - cards.add(new SetCardInfo("Curse of Thirst", 81, Rarity.SPECIAL, mage.cards.c.CurseOfThirst.class)); - cards.add(new SetCardInfo("Curse of Wizardry", 47, Rarity.SPECIAL, mage.cards.c.CurseOfWizardry.class)); - cards.add(new SetCardInfo("Dauntless Dourbark", 12, Rarity.SPECIAL, mage.cards.d.DauntlessDourbark.class)); - cards.add(new SetCardInfo("Deathless Angel", 49, Rarity.SPECIAL, mage.cards.d.DeathlessAngel.class)); - cards.add(new SetCardInfo("Duergar Hedge-Mage", 19, Rarity.SPECIAL, mage.cards.d.DuergarHedgeMage.class)); - cards.add(new SetCardInfo("Emeria Angel", 35, Rarity.SPECIAL, mage.cards.e.EmeriaAngel.class)); - cards.add(new SetCardInfo("Fiery Temper", 3, Rarity.SPECIAL, mage.cards.f.FieryTemper.class)); - cards.add(new SetCardInfo("Fling", 69, Rarity.SPECIAL, mage.cards.f.Fling.class)); - cards.add(new SetCardInfo("Gather the Townsfolk", 79, Rarity.SPECIAL, mage.cards.g.GatherTheTownsfolk.class)); - cards.add(new SetCardInfo("Golem's Heart", 60, Rarity.SPECIAL, mage.cards.g.GolemsHeart.class)); - cards.add(new SetCardInfo("Gravedigger", 16, Rarity.SPECIAL, mage.cards.g.Gravedigger.class)); - cards.add(new SetCardInfo("Hada Freeblade", 38, Rarity.SPECIAL, mage.cards.h.HadaFreeblade.class)); - cards.add(new SetCardInfo("Hellspark Elemental", 25, Rarity.SPECIAL, mage.cards.h.HellsparkElemental.class)); - cards.add(new SetCardInfo("Icatian Javelineers", 2, Rarity.SPECIAL, IcatianJavelineers.class)); - cards.add(new SetCardInfo("Kalastria Highborn", 39, Rarity.SPECIAL, mage.cards.k.KalastriaHighborn.class)); - cards.add(new SetCardInfo("Kor Duelist", 32, Rarity.SPECIAL, mage.cards.k.KorDuelist.class)); - cards.add(new SetCardInfo("Kor Firewalker", 36, Rarity.SPECIAL, mage.cards.k.KorFirewalker.class)); - cards.add(new SetCardInfo("Lava Axe", 13, Rarity.SPECIAL, mage.cards.l.LavaAxe.class)); - cards.add(new SetCardInfo("Leatherback Baloth", 37, Rarity.SPECIAL, mage.cards.l.LeatherbackBaloth.class)); - cards.add(new SetCardInfo("Llanowar Elves", 9, Rarity.SPECIAL, mage.cards.l.LlanowarElves.class)); - cards.add(new SetCardInfo("Marisi's Twinclaws", 26, Rarity.SPECIAL, mage.cards.m.MarisisTwinclaws.class)); - cards.add(new SetCardInfo("Master's Call", 64, Rarity.SPECIAL, mage.cards.m.MastersCall.class)); - cards.add(new SetCardInfo("Maul Splicer", 72, Rarity.SPECIAL, mage.cards.m.MaulSplicer.class)); - cards.add(new SetCardInfo("Mind Control", 30, Rarity.SPECIAL, mage.cards.m.MindControl.class)); - cards.add(new SetCardInfo("Mind Stone", 11, Rarity.SPECIAL, mage.cards.m.MindStone.class)); - cards.add(new SetCardInfo("Mogg Fanatic", 10, Rarity.SPECIAL, mage.cards.m.MoggFanatic.class)); - cards.add(new SetCardInfo("Mycoid Shepherd", 28, Rarity.SPECIAL, mage.cards.m.MycoidShepherd.class)); - cards.add(new SetCardInfo("Naya Sojourners", 29, Rarity.SPECIAL, mage.cards.n.NayaSojourners.class)); - cards.add(new SetCardInfo("Nearheath Stalker", 82, Rarity.SPECIAL, mage.cards.n.NearheathStalker.class)); - cards.add(new SetCardInfo("Nissa's Chosen", 34, Rarity.SPECIAL, mage.cards.n.NissasChosen.class)); - cards.add(new SetCardInfo("Oona's Blackguard", 15, Rarity.SPECIAL, mage.cards.o.OonasBlackguard.class)); - cards.add(new SetCardInfo("Pathrazer of Ulamog", 46, Rarity.SPECIAL, mage.cards.p.PathrazerOfUlamog.class)); - cards.add(new SetCardInfo("Path to Exile", 24, Rarity.SPECIAL, mage.cards.p.PathToExile.class)); - cards.add(new SetCardInfo("Plague Myr", 65, Rarity.SPECIAL, mage.cards.p.PlagueMyr.class)); - cards.add(new SetCardInfo("Plague Stinger", 59, Rarity.SPECIAL, mage.cards.p.PlagueStinger.class)); - cards.add(new SetCardInfo("Reckless Wurm", 6, Rarity.SPECIAL, mage.cards.r.RecklessWurm.class)); - cards.add(new SetCardInfo("Rise from the Grave", 31, Rarity.SPECIAL, mage.cards.r.RiseFromTheGrave.class)); - cards.add(new SetCardInfo("Selkie Hedge-Mage", 20, Rarity.SPECIAL, mage.cards.s.SelkieHedgeMage.class)); - cards.add(new SetCardInfo("Shrine of Burning Rage", 73, Rarity.SPECIAL, mage.cards.s.ShrineOfBurningRage.class)); - cards.add(new SetCardInfo("Signal Pest", 66, Rarity.SPECIAL, mage.cards.s.SignalPest.class)); - cards.add(new SetCardInfo("Skinrender", 63, Rarity.SPECIAL, mage.cards.s.Skinrender.class)); - cards.add(new SetCardInfo("Slave of Bolas", 27, Rarity.SPECIAL, mage.cards.s.SlaveOfBolas.class)); - cards.add(new SetCardInfo("Sprouting Thrinax", 21, Rarity.SPECIAL, mage.cards.s.SproutingThrinax.class)); - cards.add(new SetCardInfo("Staggershock", 48, Rarity.SPECIAL, mage.cards.s.Staggershock.class)); - cards.add(new SetCardInfo("Sylvan Ranger", 70, Rarity.SPECIAL, mage.cards.s.SylvanRanger.class)); - cards.add(new SetCardInfo("Syphon Mind", 40, Rarity.SPECIAL, mage.cards.s.SyphonMind.class)); - cards.add(new SetCardInfo("Tormented Soul", 76, Rarity.SPECIAL, mage.cards.t.TormentedSoul.class)); - cards.add(new SetCardInfo("Vampire Nighthawk", 33, Rarity.SPECIAL, mage.cards.v.VampireNighthawk.class)); - cards.add(new SetCardInfo("Vault Skirge", 71, Rarity.SPECIAL, mage.cards.v.VaultSkirge.class)); - cards.add(new SetCardInfo("Wilt-Leaf Cavaliers", 18, Rarity.SPECIAL, mage.cards.w.WiltLeafCavaliers.class)); - cards.add(new SetCardInfo("Wood Elves", 1, Rarity.SPECIAL, mage.cards.w.WoodElves.class)); - cards.add(new SetCardInfo("Woolly Thoctar", 22, Rarity.SPECIAL, mage.cards.w.WoollyThoctar.class)); - cards.add(new SetCardInfo("Yixlid Jailer", 7, Rarity.SPECIAL, mage.cards.y.YixlidJailer.class)); - cards.add(new SetCardInfo("Zoetic Cavern", 8, Rarity.SPECIAL, mage.cards.z.ZoeticCavern.class)); - } -} diff --git a/Mage.Verify/src/main/java/mage/verify/MtgJson.java b/Mage.Verify/src/main/java/mage/verify/MtgJson.java index 287aecef3d..1919f8db0f 100644 --- a/Mage.Verify/src/main/java/mage/verify/MtgJson.java +++ b/Mage.Verify/src/main/java/mage/verify/MtgJson.java @@ -27,7 +27,8 @@ public final class MtgJson { mtgJsonToXMageCodes.put("pPRE", "PTC"); mtgJsonToXMageCodes.put("pMPR", "MPRP"); mtgJsonToXMageCodes.put("pMEI", "MBP"); - mtgJsonToXMageCodes.put("pGTW", "GRC"); // pGTW - Gateway = GRC - WPN Gateway ??? + mtgJsonToXMageCodes.put("pGTW", "GRC"); // pGTW - Gateway = GRC (WPN + Gateway in one inner set) + mtgJsonToXMageCodes.put("pWPN", "GRC"); // pWPN - Wizards Play Network = GRC (WPN + Gateway in one inner set) mtgJsonToXMageCodes.put("pGRU", "GUR"); mtgJsonToXMageCodes.put("pGPX", "GPX"); mtgJsonToXMageCodes.put("pFNM", "FNMP"); @@ -41,18 +42,22 @@ public final class MtgJson { mtgJsonToXMageCodes.put("DD3_DVD", "DDC"); mtgJsonToXMageCodes.put("NMS", "NEM"); mtgJsonToXMageCodes.put("MPS_AKH", "MPS-AKH"); + mtgJsonToXMageCodes.put("FRF_UGIN", "UGIN"); + mtgJsonToXMageCodes.put("pCMP", "CP"); // revert search - for(Map.Entry entry: mtgJsonToXMageCodes.entrySet()){ + for (Map.Entry entry : mtgJsonToXMageCodes.entrySet()) { xMageToMtgJsonCodes.put(entry.getValue(), entry.getKey()); } } - private MtgJson() {} + private MtgJson() { + } private static final class CardHolder { private static final Map cards; + static { try { cards = loadAllCards(); @@ -65,6 +70,7 @@ public final class MtgJson { private static final class SetHolder { private static final Map sets; + static { try { sets = loadAllSets(); @@ -75,11 +81,13 @@ public final class MtgJson { } private static Map loadAllCards() throws IOException { - return readFromZip("AllCards.json.zip", new TypeReference>() {}); + return readFromZip("AllCards.json.zip", new TypeReference>() { + }); } private static Map loadAllSets() throws IOException { - return readFromZip("AllSets.json.zip", new TypeReference>() {}); + return readFromZip("AllSets.json.zip", new TypeReference>() { + }); } private static T readFromZip(String filename, TypeReference ref) throws IOException { diff --git a/Utils/known-sets.txt b/Utils/known-sets.txt index ad1a34fa35..8930efa547 100644 --- a/Utils/known-sets.txt +++ b/Utils/known-sets.txt @@ -200,6 +200,6 @@ Welcome Deck 2016|WelcomeDeck2016| Welcome Deck 2017|WelcomeDeck2017| World Magic Cup Qualifier|WorldMagicCupQualifier| Worldwake|Worldwake| -WPN Gateway|WPNGateway| +WPN Gateway|WPNAndGatewayPromos| Zendikar|Zendikar| Zendikar Expeditions|ZendikarExpeditions| \ No newline at end of file From 1f239b28b3d1b806ae8fae52d2b147d7b5e55b09 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 3 Oct 2018 13:01:40 -0400 Subject: [PATCH 016/167] added GRN guild kit set --- .../card/dl/sources/ScryfallImageSource.java | 9 +- Mage.Sets/src/mage/sets/GuildKit1.java | 151 ++++++++++++++++++ 2 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/GuildKit1.java diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 29b907198c..17d8f69d07 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -1,14 +1,10 @@ package org.mage.plugins.card.dl.sources; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Set; import mage.client.dialog.PreferencesDialog; import org.mage.plugins.card.images.CardDownloadData; +import java.util.*; + /** * @author Quercitron, JayDi85 */ @@ -234,6 +230,7 @@ public enum ScryfallImageSource implements CardImageSource { supportedSets.add("M19"); supportedSets.add("GS1"); supportedSets.add("GRN"); + supportedSets.add("GK1"); // supportedSets.add("EURO"); supportedSets.add("GPX"); diff --git a/Mage.Sets/src/mage/sets/GuildKit1.java b/Mage.Sets/src/mage/sets/GuildKit1.java new file mode 100644 index 0000000000..1909b3b238 --- /dev/null +++ b/Mage.Sets/src/mage/sets/GuildKit1.java @@ -0,0 +1,151 @@ + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author TheElk801 + */ +public final class GuildKit1 extends ExpansionSet { + + private static final GuildKit1 instance = new GuildKit1(); + + public static GuildKit1 getInstance() { + return instance; + } + + private GuildKit1() { + super("Guilds of Ravnica Guild Kits", "GK1", ExpansionSet.buildDate(2018, 11, 2), SetType.SUPPLEMENTAL); + this.blockName = "Guild Kits"; + this.hasBasicLands = true; + cards.add(new SetCardInfo("Abrupt Decay", 57, Rarity.RARE, mage.cards.a.AbruptDecay.class)); + cards.add(new SetCardInfo("Advent of the Wurm", 107, Rarity.RARE, mage.cards.a.AdventOfTheWurm.class)); + cards.add(new SetCardInfo("Agrus Kos, Wojek Veteran", 83, Rarity.RARE, mage.cards.a.AgrusKosWojekVeteran.class)); + cards.add(new SetCardInfo("Armada Wurm", 108, Rarity.MYTHIC, mage.cards.a.ArmadaWurm.class)); + cards.add(new SetCardInfo("Aurelia, the Warleader", 77, Rarity.MYTHIC, mage.cards.a.AureliaTheWarleader.class)); + cards.add(new SetCardInfo("Bomber Corps", 80, Rarity.COMMON, mage.cards.b.BomberCorps.class)); + cards.add(new SetCardInfo("Boros Charm", 84, Rarity.UNCOMMON, mage.cards.b.BorosCharm.class)); + cards.add(new SetCardInfo("Boros Elite", 78, Rarity.UNCOMMON, mage.cards.b.BorosElite.class)); + cards.add(new SetCardInfo("Boros Garrison", 98, Rarity.COMMON, mage.cards.b.BorosGarrison.class)); + cards.add(new SetCardInfo("Boros Keyrune", 96, Rarity.UNCOMMON, mage.cards.b.BorosKeyrune.class)); + cards.add(new SetCardInfo("Boros Reckoner", 85, Rarity.RARE, mage.cards.b.BorosReckoner.class)); + cards.add(new SetCardInfo("Boros Signet", 97, Rarity.COMMON, mage.cards.b.BorosSignet.class)); + cards.add(new SetCardInfo("Boros Swiftblade", 86, Rarity.UNCOMMON, mage.cards.b.BorosSwiftblade.class)); + cards.add(new SetCardInfo("Brightflame", 87, Rarity.RARE, mage.cards.b.Brightflame.class)); + cards.add(new SetCardInfo("Call of the Conclave", 109, Rarity.UNCOMMON, mage.cards.c.CallOfTheConclave.class)); + cards.add(new SetCardInfo("Call of the Nightwing", 8, Rarity.UNCOMMON, mage.cards.c.CallOfTheNightwing.class)); + cards.add(new SetCardInfo("Centaur Healer", 110, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); + cards.add(new SetCardInfo("Cerebral Vortex", 35, Rarity.RARE, mage.cards.c.CerebralVortex.class)); + cards.add(new SetCardInfo("Char", 28, Rarity.RARE, mage.cards.c.Char.class)); + cards.add(new SetCardInfo("Circu, Dimir Lobotomist", 9, Rarity.RARE, mage.cards.c.CircuDimirLobotomist.class)); + cards.add(new SetCardInfo("Consuming Aberration", 10, Rarity.RARE, mage.cards.c.ConsumingAberration.class)); + cards.add(new SetCardInfo("Daring Skyjek", 79, Rarity.COMMON, mage.cards.d.DaringSkyjek.class)); + cards.add(new SetCardInfo("Darkblast", 51, Rarity.UNCOMMON, mage.cards.d.Darkblast.class)); + cards.add(new SetCardInfo("Deadbridge Chant", 58, Rarity.MYTHIC, mage.cards.d.DeadbridgeChant.class)); + cards.add(new SetCardInfo("Deadbridge Goliath", 55, Rarity.RARE, mage.cards.d.DeadbridgeGoliath.class)); + cards.add(new SetCardInfo("Deathrite Shaman", 59, Rarity.RARE, mage.cards.d.DeathriteShaman.class)); + cards.add(new SetCardInfo("Devouring Light", 103, Rarity.UNCOMMON, mage.cards.d.DevouringLight.class)); + cards.add(new SetCardInfo("Dimir Aqueduct", 23, Rarity.COMMON, mage.cards.d.DimirAqueduct.class)); + cards.add(new SetCardInfo("Dimir Charm", 11, Rarity.UNCOMMON, mage.cards.d.DimirCharm.class)); + cards.add(new SetCardInfo("Dimir Doppelganger", 12, Rarity.RARE, mage.cards.d.DimirDoppelganger.class)); + cards.add(new SetCardInfo("Dimir Guildmage", 13, Rarity.UNCOMMON, mage.cards.d.DimirGuildmage.class)); + cards.add(new SetCardInfo("Dimir Signet", 22, Rarity.COMMON, mage.cards.d.DimirSignet.class)); + cards.add(new SetCardInfo("Dinrova Horror", 14, Rarity.UNCOMMON, mage.cards.d.DinrovaHorror.class)); + cards.add(new SetCardInfo("Djinn Illuminatus", 36, Rarity.RARE, mage.cards.d.DjinnIlluminatus.class)); + cards.add(new SetCardInfo("Drown in Filth", 60, Rarity.COMMON, mage.cards.d.DrownInFilth.class)); + cards.add(new SetCardInfo("Dryad Militant", 111, Rarity.UNCOMMON, mage.cards.d.DryadMilitant.class)); + cards.add(new SetCardInfo("Electrickery", 29, Rarity.COMMON, mage.cards.e.Electrickery.class)); + cards.add(new SetCardInfo("Electrolyze", 37, Rarity.UNCOMMON, mage.cards.e.Electrolyze.class)); + cards.add(new SetCardInfo("Elves of Deep Shadow", 56, Rarity.COMMON, mage.cards.e.ElvesOfDeepShadow.class)); + cards.add(new SetCardInfo("Etrata, the Silencer", 1, Rarity.RARE, mage.cards.e.EtrataTheSilencer.class)); + cards.add(new SetCardInfo("Firemane Angel", 88, Rarity.RARE, mage.cards.f.FiremaneAngel.class)); + cards.add(new SetCardInfo("Firemane Avenger", 89, Rarity.RARE, mage.cards.f.FiremaneAvenger.class)); + cards.add(new SetCardInfo("Forest", 76, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 127, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Frenzied Goblin", 81, Rarity.UNCOMMON, mage.cards.f.FrenziedGoblin.class)); + cards.add(new SetCardInfo("Gather Courage", 105, Rarity.COMMON, mage.cards.g.GatherCourage.class)); + cards.add(new SetCardInfo("Gaze of Granite", 61, Rarity.RARE, mage.cards.g.GazeOfGranite.class)); + cards.add(new SetCardInfo("Gelectrode", 38, Rarity.UNCOMMON, mage.cards.g.Gelectrode.class)); + cards.add(new SetCardInfo("Glare of Subdual", 112, Rarity.RARE, mage.cards.g.GlareOfSubdual.class)); + cards.add(new SetCardInfo("Glimpse the Unthinkable", 15, Rarity.RARE, mage.cards.g.GlimpseTheUnthinkable.class)); + cards.add(new SetCardInfo("Goblin Rally", 30, Rarity.UNCOMMON, mage.cards.g.GoblinRally.class)); + cards.add(new SetCardInfo("Golgari Charm", 62, Rarity.UNCOMMON, mage.cards.g.GolgariCharm.class)); + cards.add(new SetCardInfo("Golgari Rot Farm", 74, Rarity.COMMON, mage.cards.g.GolgariRotFarm.class)); + cards.add(new SetCardInfo("Golgari Signet", 73, Rarity.COMMON, mage.cards.g.GolgariSignet.class)); + cards.add(new SetCardInfo("Grave-Shell Scarab", 63, Rarity.RARE, mage.cards.g.GraveShellScarab.class)); + cards.add(new SetCardInfo("Grisly Salvage", 64, Rarity.COMMON, mage.cards.g.GrislySalvage.class)); + cards.add(new SetCardInfo("Grove of the Guardian", 124, Rarity.RARE, mage.cards.g.GroveOfTheGuardian.class)); + cards.add(new SetCardInfo("Growing Ranks", 113, Rarity.RARE, mage.cards.g.GrowingRanks.class)); + cards.add(new SetCardInfo("Guttersnipe", 31, Rarity.UNCOMMON, mage.cards.g.Guttersnipe.class)); + cards.add(new SetCardInfo("Hour of Reckoning", 104, Rarity.RARE, mage.cards.h.HourOfReckoning.class)); + cards.add(new SetCardInfo("Hypersonic Dragon", 39, Rarity.RARE, mage.cards.h.HypersonicDragon.class)); + cards.add(new SetCardInfo("Invoke the Firemind", 40, Rarity.RARE, mage.cards.i.InvokeTheFiremind.class)); + cards.add(new SetCardInfo("Island", 24, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 48, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Izoni, Thousand-Eyed", 50, Rarity.RARE, mage.cards.i.IzoniThousandEyed.class)); + cards.add(new SetCardInfo("Izzet Boilerworks", 47, Rarity.COMMON, mage.cards.i.IzzetBoilerworks.class)); + cards.add(new SetCardInfo("Izzet Charm", 41, Rarity.UNCOMMON, mage.cards.i.IzzetCharm.class)); + cards.add(new SetCardInfo("Izzet Signet", 46, Rarity.COMMON, mage.cards.i.IzzetSignet.class)); + cards.add(new SetCardInfo("Jarad, Golgari Lich Lord", 65, Rarity.MYTHIC, mage.cards.j.JaradGolgariLichLord.class)); + cards.add(new SetCardInfo("Korozda Guildmage", 66, Rarity.UNCOMMON, mage.cards.k.KorozdaGuildmage.class)); + cards.add(new SetCardInfo("Last Gasp", 5, Rarity.COMMON, mage.cards.l.LastGasp.class)); + cards.add(new SetCardInfo("Lazav, Dimir Mastermind", 16, Rarity.MYTHIC, mage.cards.l.LazavDimirMastermind.class)); + cards.add(new SetCardInfo("Legion Loyalist", 82, Rarity.RARE, mage.cards.l.LegionLoyalist.class)); + cards.add(new SetCardInfo("Lightning Helix", 90, Rarity.UNCOMMON, mage.cards.l.LightningHelix.class)); + cards.add(new SetCardInfo("Lotleth Troll", 67, Rarity.RARE, mage.cards.l.LotlethTroll.class)); + cards.add(new SetCardInfo("Loxodon Hierarch", 114, Rarity.RARE, mage.cards.l.LoxodonHierarch.class)); + cards.add(new SetCardInfo("Martial Glory", 91, Rarity.COMMON, mage.cards.m.MartialGlory.class)); + cards.add(new SetCardInfo("Master Warcraft", 92, Rarity.RARE, mage.cards.m.MasterWarcraft.class)); + cards.add(new SetCardInfo("Mirko Vosk, Mind Drinker", 17, Rarity.RARE, mage.cards.m.MirkoVoskMindDrinker.class)); + cards.add(new SetCardInfo("Mizzium Mortars", 32, Rarity.RARE, mage.cards.m.MizziumMortars.class)); + cards.add(new SetCardInfo("Moroii", 18, Rarity.UNCOMMON, mage.cards.m.Moroii.class)); + cards.add(new SetCardInfo("Mountain", 49, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 101, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Netherborn Phalanx", 6, Rarity.UNCOMMON, mage.cards.n.NetherbornPhalanx.class)); + cards.add(new SetCardInfo("Nightveil Specter", 19, Rarity.RARE, mage.cards.n.NightveilSpecter.class)); + cards.add(new SetCardInfo("Niv-Mizzet, the Firemind", 26, Rarity.RARE, mage.cards.n.NivMizzetTheFiremind.class)); + cards.add(new SetCardInfo("Nivix Guildmage", 42, Rarity.UNCOMMON, mage.cards.n.NivixGuildmage.class)); + cards.add(new SetCardInfo("Plains", 100, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 126, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Pollenbright Wings", 115, Rarity.UNCOMMON, mage.cards.p.PollenbrightWings.class)); + cards.add(new SetCardInfo("Privileged Position", 116, Rarity.RARE, mage.cards.p.PrivilegedPosition.class)); + cards.add(new SetCardInfo("Putrefy", 68, Rarity.UNCOMMON, mage.cards.p.Putrefy.class)); + cards.add(new SetCardInfo("Pyromatics", 33, Rarity.COMMON, mage.cards.p.Pyromatics.class)); + cards.add(new SetCardInfo("Razia, Boros Archangel", 93, Rarity.RARE, mage.cards.r.RaziaBorosArchangel.class)); + cards.add(new SetCardInfo("Ribbons of Night", 7, Rarity.UNCOMMON, mage.cards.r.RibbonsOfNight.class)); + cards.add(new SetCardInfo("Savra, Queen of the Golgari", 69, Rarity.RARE, mage.cards.s.SavraQueenOfTheGolgari.class)); + cards.add(new SetCardInfo("Scatter the Seeds", 106, Rarity.COMMON, mage.cards.s.ScatterTheSeeds.class)); + cards.add(new SetCardInfo("Selesnya Charm", 117, Rarity.UNCOMMON, mage.cards.s.SelesnyaCharm.class)); + cards.add(new SetCardInfo("Selesnya Evangel", 118, Rarity.COMMON, mage.cards.s.SelesnyaEvangel.class)); + cards.add(new SetCardInfo("Selesnya Guildmage", 119, Rarity.UNCOMMON, mage.cards.s.SelesnyaGuildmage.class)); + cards.add(new SetCardInfo("Selesnya Sanctuary", 125, Rarity.COMMON, mage.cards.s.SelesnyaSanctuary.class)); + cards.add(new SetCardInfo("Selesnya Signet", 123, Rarity.COMMON, mage.cards.s.SelesnyaSignet.class)); + cards.add(new SetCardInfo("Shambling Shell", 70, Rarity.COMMON, mage.cards.s.ShamblingShell.class)); + cards.add(new SetCardInfo("Shattering Spree", 34, Rarity.UNCOMMON, mage.cards.s.ShatteringSpree.class)); + cards.add(new SetCardInfo("Sisters of Stone Death", 71, Rarity.RARE, mage.cards.s.SistersOfStoneDeath.class)); + cards.add(new SetCardInfo("Slum Reaper", 52, Rarity.UNCOMMON, mage.cards.s.SlumReaper.class)); + cards.add(new SetCardInfo("Spark Trooper", 94, Rarity.RARE, mage.cards.s.SparkTrooper.class)); + cards.add(new SetCardInfo("Stinkweed Imp", 53, Rarity.COMMON, mage.cards.s.StinkweedImp.class)); + cards.add(new SetCardInfo("Stitch in Time", 43, Rarity.RARE, mage.cards.s.StitchInTime.class)); + cards.add(new SetCardInfo("Stolen Identity", 2, Rarity.RARE, mage.cards.s.StolenIdentity.class)); + cards.add(new SetCardInfo("Sundering Growth", 120, Rarity.COMMON, mage.cards.s.SunderingGrowth.class)); + cards.add(new SetCardInfo("Sunhome Guildmage", 95, Rarity.UNCOMMON, mage.cards.s.SunhomeGuildmage.class)); + cards.add(new SetCardInfo("Sunhome, Fortress of the Legion", 99, Rarity.UNCOMMON, mage.cards.s.SunhomeFortressOfTheLegion.class)); + cards.add(new SetCardInfo("Swamp", 25, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 75, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Syncopate", 3, Rarity.UNCOMMON, mage.cards.s.Syncopate.class)); + cards.add(new SetCardInfo("Szadek, Lord of Secrets", 20, Rarity.RARE, mage.cards.s.SzadekLordOfSecrets.class)); + cards.add(new SetCardInfo("Telling Time", 4, Rarity.UNCOMMON, mage.cards.t.TellingTime.class)); + cards.add(new SetCardInfo("Thunderheads", 27, Rarity.UNCOMMON, mage.cards.t.Thunderheads.class)); + cards.add(new SetCardInfo("Tibor and Lumia", 44, Rarity.RARE, mage.cards.t.TiborAndLumia.class)); + cards.add(new SetCardInfo("Tolsimir Wolfblood", 121, Rarity.RARE, mage.cards.t.TolsimirWolfblood.class)); + cards.add(new SetCardInfo("Treasured Find", 72, Rarity.UNCOMMON, mage.cards.t.TreasuredFind.class)); + cards.add(new SetCardInfo("Trostani, Selesnya's Voice", 102, Rarity.MYTHIC, mage.cards.t.TrostaniSelesnyasVoice.class)); + cards.add(new SetCardInfo("Turn // Burn", 45, Rarity.UNCOMMON, mage.cards.t.TurnBurn.class)); + cards.add(new SetCardInfo("Vigor Mortis", 54, Rarity.UNCOMMON, mage.cards.v.VigorMortis.class)); + cards.add(new SetCardInfo("Warped Physique", 21, Rarity.UNCOMMON, mage.cards.w.WarpedPhysique.class)); + cards.add(new SetCardInfo("Watchwolf", 122, Rarity.UNCOMMON, mage.cards.w.Watchwolf.class)); + } +} From 12eec8e1b8b57918a9b5dcaefe45ba1f388de9f3 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 22:06:18 +0400 Subject: [PATCH 017/167] * Fixed that some sets uses same images for multi-images cards: * Guilds of Ravnica (GRN), Commander Anthology Volume II (CM2), Battlebond (BBD); * From the Vault: Transform (V17), Media Inserts (MBP), WPN and Gateway Promos (GRC); --- Mage.Sets/src/mage/sets/Battlebond.java | 8 ++-- .../mage/sets/CommanderAnthologyVolumeII.java | 16 +++---- .../mage/sets/DuelDecksMerfolkVsGoblins.java | 16 +++---- .../mage/sets/DuelsOfThePlaneswalkers.java | 32 +++++++------- .../src/mage/sets/FromTheVaultTransform.java | 4 +- Mage.Sets/src/mage/sets/GuildsOfRavnica.java | 23 +++++----- .../src/mage/sets/HourOfDevastation.java | 20 ++++----- Mage.Sets/src/mage/sets/Ixalan.java | 43 +++++++++---------- Mage.Sets/src/mage/sets/MediaInserts.java | 8 ++-- .../src/mage/sets/WPNAndGatewayPromos.java | 8 ++-- .../main/java/mage/cards/CardGraphicInfo.java | 2 +- .../src/main/java/mage/cards/CardSetInfo.java | 7 +-- 12 files changed, 91 insertions(+), 96 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 3bbc82b5d0..687614bd2d 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -212,8 +212,8 @@ public final class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Rhox Brute", 227, Rarity.COMMON, mage.cards.r.RhoxBrute.class)); cards.add(new SetCardInfo("Riptide Crab", 228, Rarity.COMMON, mage.cards.r.RiptideCrab.class)); cards.add(new SetCardInfo("Rotfeaster Maggot", 157, Rarity.COMMON, mage.cards.r.RotfeasterMaggot.class)); - cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); - cards.add(new SetCardInfo("Rowan Kenrith", 256, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); + cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rowan Kenrith", 256, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Royal Trooper", 104, Rarity.COMMON, mage.cards.r.RoyalTrooper.class)); cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); cards.add(new SetCardInfo("Saddleback Lagac", 211, Rarity.COMMON, mage.cards.s.SaddlebackLagac.class)); @@ -279,8 +279,8 @@ public final class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Wandering Wolf", 216, Rarity.COMMON, mage.cards.w.WanderingWolf.class)); cards.add(new SetCardInfo("War's Toll", 187, Rarity.RARE, mage.cards.w.WarsToll.class)); cards.add(new SetCardInfo("Watercourser", 137, Rarity.COMMON, mage.cards.w.Watercourser.class)); - cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); - cards.add(new SetCardInfo("Will Kenrith", 255, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); + cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Will Kenrith", 255, Rarity.MYTHIC, mage.cards.w.WillKenrith.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wrap in Flames", 188, Rarity.COMMON, mage.cards.w.WrapInFlames.class)); cards.add(new SetCardInfo("Yotian Soldier", 249, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); cards.add(new SetCardInfo("Zndrsplt's Judgment", 43, Rarity.RARE, mage.cards.z.ZndrspltsJudgment.class)); diff --git a/Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java b/Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java index 1d0d7240e3..ba3b6ac123 100644 --- a/Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java +++ b/Mage.Sets/src/mage/sets/CommanderAnthologyVolumeII.java @@ -136,8 +136,8 @@ public class CommanderAnthologyVolumeII extends ExpansionSet { cards.add(new SetCardInfo("Gisela, Blade of Goldnight", 9, Rarity.MYTHIC, mage.cards.g.GiselaBladeOfGoldnight.class)); cards.add(new SetCardInfo("Goblin Welder", 101, Rarity.RARE, mage.cards.g.GoblinWelder.class)); cards.add(new SetCardInfo("Golgari Rot Farm", 254, Rarity.UNCOMMON, mage.cards.g.GolgariRotFarm.class)); - cards.add(new SetCardInfo("Golgari Signet", 191, Rarity.COMMON, mage.cards.g.GolgariSignet.class)); - cards.add(new SetCardInfo("Golgari Signet", 192, Rarity.COMMON, mage.cards.g.GolgariSignet.class)); + cards.add(new SetCardInfo("Golgari Signet", 191, Rarity.COMMON, mage.cards.g.GolgariSignet.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Golgari Signet", 192, Rarity.COMMON, mage.cards.g.GolgariSignet.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grave Pact", 65, Rarity.RARE, mage.cards.g.GravePact.class)); cards.add(new SetCardInfo("Gravedigger", 66, Rarity.COMMON, mage.cards.g.Gravedigger.class)); cards.add(new SetCardInfo("Great Furnace", 255, Rarity.COMMON, mage.cards.g.GreatFurnace.class)); @@ -251,14 +251,14 @@ public class CommanderAnthologyVolumeII extends ExpansionSet { cards.add(new SetCardInfo("Shared Trauma", 76, Rarity.RARE, mage.cards.s.SharedTrauma.class)); cards.add(new SetCardInfo("Sign in Blood", 77, Rarity.COMMON, mage.cards.s.SignInBlood.class)); cards.add(new SetCardInfo("Simic Growth Chamber", 267, Rarity.COMMON, mage.cards.s.SimicGrowthChamber.class)); - cards.add(new SetCardInfo("Simic Signet", 215, Rarity.COMMON, mage.cards.s.SimicSignet.class)); - cards.add(new SetCardInfo("Simic Signet", 216, Rarity.COMMON, mage.cards.s.SimicSignet.class)); + cards.add(new SetCardInfo("Simic Signet", 215, Rarity.COMMON, mage.cards.s.SimicSignet.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Simic Signet", 216, Rarity.COMMON, mage.cards.s.SimicSignet.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Skullbriar, the Walking Grave", 165, Rarity.RARE, mage.cards.s.SkullbriarTheWalkingGrave.class)); cards.add(new SetCardInfo("Slipstream Eel", 49, Rarity.COMMON, mage.cards.s.SlipstreamEel.class)); cards.add(new SetCardInfo("Smoldering Crater", 268, Rarity.COMMON, mage.cards.s.SmolderingCrater.class)); cards.add(new SetCardInfo("Sol Ring", 217, Rarity.UNCOMMON, mage.cards.s.SolRing.class)); - cards.add(new SetCardInfo("Solemn Simulacrum", 218, Rarity.RARE, mage.cards.s.SolemnSimulacrum.class)); - cards.add(new SetCardInfo("Solemn Simulacrum", 219, Rarity.RARE, mage.cards.s.SolemnSimulacrum.class)); + cards.add(new SetCardInfo("Solemn Simulacrum", 218, Rarity.RARE, mage.cards.s.SolemnSimulacrum.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Solemn Simulacrum", 219, Rarity.RARE, mage.cards.s.SolemnSimulacrum.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Solidarity of Heroes", 144, Rarity.UNCOMMON, mage.cards.s.SolidarityOfHeroes.class)); cards.add(new SetCardInfo("Spell Crumple", 50, Rarity.UNCOMMON, mage.cards.s.SpellCrumple.class)); cards.add(new SetCardInfo("Spine of Ish Sah", 220, Rarity.RARE, mage.cards.s.SpineOfIshSah.class)); @@ -288,8 +288,8 @@ public class CommanderAnthologyVolumeII extends ExpansionSet { cards.add(new SetCardInfo("Syphon Mind", 80, Rarity.COMMON, mage.cards.s.SyphonMind.class)); cards.add(new SetCardInfo("Szadek, Lord of Secrets", 168, Rarity.RARE, mage.cards.s.SzadekLordOfSecrets.class)); cards.add(new SetCardInfo("Taurean Mauler", 122, Rarity.RARE, mage.cards.t.TaureanMauler.class)); - cards.add(new SetCardInfo("Temple of the False God", 271, Rarity.UNCOMMON, mage.cards.t.TempleOfTheFalseGod.class)); - cards.add(new SetCardInfo("Temple of the False God", 272, Rarity.UNCOMMON, mage.cards.t.TempleOfTheFalseGod.class)); + cards.add(new SetCardInfo("Temple of the False God", 271, Rarity.UNCOMMON, mage.cards.t.TempleOfTheFalseGod.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Temple of the False God", 272, Rarity.UNCOMMON, mage.cards.t.TempleOfTheFalseGod.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Terramorphic Expanse", 273, Rarity.COMMON, mage.cards.t.TerramorphicExpanse.class)); cards.add(new SetCardInfo("Tezzeret's Gambit", 51, Rarity.UNCOMMON, mage.cards.t.TezzeretsGambit.class)); cards.add(new SetCardInfo("The Mimeoplasm", 1, Rarity.MYTHIC, mage.cards.t.TheMimeoplasm.class)); diff --git a/Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java b/Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java index ee9d989903..2c0babb3ef 100644 --- a/Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java +++ b/Mage.Sets/src/mage/sets/DuelDecksMerfolkVsGoblins.java @@ -53,10 +53,10 @@ public final class DuelDecksMerfolkVsGoblins extends ExpansionSet { cards.add(new SetCardInfo("Harbinger of the Tides", 7, Rarity.RARE, mage.cards.h.HarbingerOfTheTides.class)); cards.add(new SetCardInfo("Hordeling Outburst", 51, Rarity.UNCOMMON, mage.cards.h.HordelingOutburst.class)); cards.add(new SetCardInfo("Inkfathom Divers", 8, Rarity.COMMON, mage.cards.i.InkfathomDivers.class)); - cards.add(new SetCardInfo("Island", 28, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 29, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 30, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 31, Rarity.LAND, mage.cards.basiclands.Island.class)); + cards.add(new SetCardInfo("Island", 28, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 29, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 30, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 31, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Krenko's Command", 53, Rarity.COMMON, mage.cards.k.KrenkosCommand.class)); cards.add(new SetCardInfo("Krenko, Mob Boss", 52, Rarity.RARE, mage.cards.k.KrenkoMobBoss.class)); cards.add(new SetCardInfo("Lonely Sandbar", 27, Rarity.COMMON, mage.cards.l.LonelySandbar.class)); @@ -68,10 +68,10 @@ public final class DuelDecksMerfolkVsGoblins extends ExpansionSet { cards.add(new SetCardInfo("Merrow Reejerey", 13, Rarity.UNCOMMON, mage.cards.m.MerrowReejerey.class)); cards.add(new SetCardInfo("Mind Spring", 14, Rarity.RARE, mage.cards.m.MindSpring.class)); cards.add(new SetCardInfo("Misdirection", 15, Rarity.RARE, mage.cards.m.Misdirection.class)); - cards.add(new SetCardInfo("Mountain", 60, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 61, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 62, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 63, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Mountain", 60, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 61, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 62, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 63, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Relentless Assault", 54, Rarity.RARE, mage.cards.r.RelentlessAssault.class)); cards.add(new SetCardInfo("Rootwater Hunter", 16, Rarity.UNCOMMON, mage.cards.r.RootwaterHunter.class)); cards.add(new SetCardInfo("Scroll Thief", 17, Rarity.COMMON, mage.cards.s.ScrollThief.class)); diff --git a/Mage.Sets/src/mage/sets/DuelsOfThePlaneswalkers.java b/Mage.Sets/src/mage/sets/DuelsOfThePlaneswalkers.java index 3851143763..0c6d15850f 100644 --- a/Mage.Sets/src/mage/sets/DuelsOfThePlaneswalkers.java +++ b/Mage.Sets/src/mage/sets/DuelsOfThePlaneswalkers.java @@ -53,10 +53,10 @@ public final class DuelsOfThePlaneswalkers extends ExpansionSet { cards.add(new SetCardInfo("Essence Scatter", 8, Rarity.COMMON, mage.cards.e.EssenceScatter.class)); cards.add(new SetCardInfo("Evacuation", 9, Rarity.RARE, mage.cards.e.Evacuation.class)); cards.add(new SetCardInfo("Eyeblight's Ending", 25, Rarity.COMMON, mage.cards.e.EyeblightsEnding.class)); - cards.add(new SetCardInfo("Forest", 110, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 111, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 112, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 113, Rarity.LAND, mage.cards.basiclands.Forest.class)); + cards.add(new SetCardInfo("Forest", 110, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 111, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 112, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 113, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Furnace of Rath", 44, Rarity.RARE, mage.cards.f.FurnaceOfRath.class)); cards.add(new SetCardInfo("Gaea's Herald", 65, Rarity.RARE, mage.cards.g.GaeasHerald.class)); cards.add(new SetCardInfo("Giant Growth", 66, Rarity.COMMON, mage.cards.g.GiantGrowth.class)); @@ -69,10 +69,10 @@ public final class DuelsOfThePlaneswalkers extends ExpansionSet { cards.add(new SetCardInfo("Immaculate Magistrate", 70, Rarity.RARE, mage.cards.i.ImmaculateMagistrate.class)); cards.add(new SetCardInfo("Imperious Perfect", 71, Rarity.UNCOMMON, mage.cards.i.ImperiousPerfect.class)); cards.add(new SetCardInfo("Incinerate", 48, Rarity.COMMON, mage.cards.i.Incinerate.class)); - cards.add(new SetCardInfo("Island", 100, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 101, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 98, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 99, Rarity.LAND, mage.cards.basiclands.Island.class)); + cards.add(new SetCardInfo("Island", 100, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 101, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 98, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 99, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jagged-Scar Archers", 72, Rarity.UNCOMMON, mage.cards.j.JaggedScarArchers.class)); cards.add(new SetCardInfo("Kamahl, Pit Fighter", 49, Rarity.RARE, mage.cards.k.KamahlPitFighter.class)); cards.add(new SetCardInfo("Kraken's Eye", 93, Rarity.UNCOMMON, mage.cards.k.KrakensEye.class)); @@ -88,10 +88,10 @@ public final class DuelsOfThePlaneswalkers extends ExpansionSet { cards.add(new SetCardInfo("Molimo, Maro-Sorcerer", 74, Rarity.RARE, mage.cards.m.MolimoMaroSorcerer.class)); cards.add(new SetCardInfo("Moonglove Winnower", 29, Rarity.COMMON, mage.cards.m.MoongloveWinnower.class)); cards.add(new SetCardInfo("Mortivore", 30, Rarity.RARE, mage.cards.m.Mortivore.class)); - cards.add(new SetCardInfo("Mountain", 106, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 107, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 108, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 109, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Mountain", 106, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 107, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 108, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 109, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Natural Spring", 75, Rarity.COMMON, mage.cards.n.NaturalSpring.class)); cards.add(new SetCardInfo("Naturalize", 76, Rarity.COMMON, mage.cards.n.Naturalize.class)); cards.add(new SetCardInfo("Nature's Spiral", 77, Rarity.UNCOMMON, mage.cards.n.NaturesSpiral.class)); @@ -111,10 +111,10 @@ public final class DuelsOfThePlaneswalkers extends ExpansionSet { cards.add(new SetCardInfo("Shock", 54, Rarity.COMMON, mage.cards.s.Shock.class)); cards.add(new SetCardInfo("Snapping Drake", 15, Rarity.COMMON, mage.cards.s.SnappingDrake.class)); cards.add(new SetCardInfo("Spined Wurm", 83, Rarity.COMMON, mage.cards.s.SpinedWurm.class)); - cards.add(new SetCardInfo("Swamp", 102, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 103, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 104, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 105, Rarity.LAND, mage.cards.basiclands.Swamp.class)); + cards.add(new SetCardInfo("Swamp", 102, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 103, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 104, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 105, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Talara's Battalion", 84, Rarity.RARE, mage.cards.t.TalarasBattalion.class)); cards.add(new SetCardInfo("Terror", 34, Rarity.COMMON, mage.cards.t.Terror.class)); cards.add(new SetCardInfo("The Rack", 95, Rarity.UNCOMMON, mage.cards.t.TheRack.class)); diff --git a/Mage.Sets/src/mage/sets/FromTheVaultTransform.java b/Mage.Sets/src/mage/sets/FromTheVaultTransform.java index ac08d9ce7a..5319234d4a 100644 --- a/Mage.Sets/src/mage/sets/FromTheVaultTransform.java +++ b/Mage.Sets/src/mage/sets/FromTheVaultTransform.java @@ -29,8 +29,8 @@ public final class FromTheVaultTransform extends ExpansionSet { cards.add(new SetCardInfo("Bloodline Keeper", 4, Rarity.MYTHIC, mage.cards.b.BloodlineKeeper.class)); cards.add(new SetCardInfo("Lord of Lineage", 1004, Rarity.MYTHIC, mage.cards.l.LordOfLineage.class)); cards.add(new SetCardInfo("Bruna, the Fading Light", 5, Rarity.MYTHIC, mage.cards.b.BrunaTheFadingLight.class)); - cards.add(new SetCardInfo("Brisela, Voice of Nightmares", 1005, Rarity.MYTHIC, mage.cards.b.BriselaVoiceOfNightmares.class)); - cards.add(new SetCardInfo("Brisela, Voice of Nightmares", 1005, Rarity.MYTHIC, mage.cards.b.BriselaVoiceOfNightmares.class)); + cards.add(new SetCardInfo("Brisela, Voice of Nightmares", 1005, Rarity.MYTHIC, mage.cards.b.BriselaVoiceOfNightmares.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Brisela, Voice of Nightmares", 1005, Rarity.MYTHIC, mage.cards.b.BriselaVoiceOfNightmares.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chandra, Fire of Kaladesh", 6, Rarity.MYTHIC, mage.cards.c.ChandraFireOfKaladesh.class)); cards.add(new SetCardInfo("Chandra, Roaring Flame", 1006, Rarity.MYTHIC, mage.cards.c.ChandraRoaringFlame.class)); cards.add(new SetCardInfo("Delver of Secrets", 7, Rarity.MYTHIC, mage.cards.d.DelverOfSecrets.class)); diff --git a/Mage.Sets/src/mage/sets/GuildsOfRavnica.java b/Mage.Sets/src/mage/sets/GuildsOfRavnica.java index a17769262d..0c9ee0fd14 100644 --- a/Mage.Sets/src/mage/sets/GuildsOfRavnica.java +++ b/Mage.Sets/src/mage/sets/GuildsOfRavnica.java @@ -2,6 +2,7 @@ package mage.sets; import java.util.ArrayList; import java.util.List; + import mage.cards.ExpansionSet; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; @@ -48,8 +49,8 @@ public final class GuildsOfRavnica extends ExpansionSet { cards.add(new SetCardInfo("Blood Operative", 63, Rarity.RARE, mage.cards.b.BloodOperative.class)); cards.add(new SetCardInfo("Book Devourer", 93, Rarity.UNCOMMON, mage.cards.b.BookDevourer.class)); cards.add(new SetCardInfo("Boros Challenger", 156, Rarity.UNCOMMON, mage.cards.b.BorosChallenger.class)); - cards.add(new SetCardInfo("Boros Guildgate", 243, Rarity.COMMON, mage.cards.b.BorosGuildgate.class)); - cards.add(new SetCardInfo("Boros Guildgate", 244, Rarity.COMMON, mage.cards.b.BorosGuildgate.class)); + cards.add(new SetCardInfo("Boros Guildgate", 243, Rarity.COMMON, mage.cards.b.BorosGuildgate.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Boros Guildgate", 244, Rarity.COMMON, mage.cards.b.BorosGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Boros Locket", 231, Rarity.COMMON, mage.cards.b.BorosLocket.class)); cards.add(new SetCardInfo("Bounty Agent", 2, Rarity.RARE, mage.cards.b.BountyAgent.class)); cards.add(new SetCardInfo("Bounty of Might", 124, Rarity.RARE, mage.cards.b.BountyOfMight.class)); @@ -87,8 +88,8 @@ public final class GuildsOfRavnica extends ExpansionSet { cards.add(new SetCardInfo("Demotion", 9, Rarity.UNCOMMON, mage.cards.d.Demotion.class)); cards.add(new SetCardInfo("Devious Cover-up", 35, Rarity.COMMON, mage.cards.d.DeviousCoverUp.class)); cards.add(new SetCardInfo("Devkarin Dissident", 127, Rarity.COMMON, mage.cards.d.DevkarinDissident.class)); - cards.add(new SetCardInfo("Dimir Guildgate", 245, Rarity.COMMON, mage.cards.d.DimirGuildgate.class)); - cards.add(new SetCardInfo("Dimir Guildgate", 246, Rarity.COMMON, mage.cards.d.DimirGuildgate.class)); + cards.add(new SetCardInfo("Dimir Guildgate", 245, Rarity.COMMON, mage.cards.d.DimirGuildgate.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dimir Guildgate", 246, Rarity.COMMON, mage.cards.d.DimirGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dimir Informant", 36, Rarity.COMMON, mage.cards.d.DimirInformant.class)); cards.add(new SetCardInfo("Dimir Locket", 234, Rarity.COMMON, mage.cards.d.DimirLocket.class)); cards.add(new SetCardInfo("Dimir Spybug", 166, Rarity.UNCOMMON, mage.cards.d.DimirSpybug.class)); @@ -130,8 +131,8 @@ public final class GuildsOfRavnica extends ExpansionSet { cards.add(new SetCardInfo("Goblin Electromancer", 174, Rarity.COMMON, mage.cards.g.GoblinElectromancer.class)); cards.add(new SetCardInfo("Goblin Locksmith", 104, Rarity.COMMON, mage.cards.g.GoblinLocksmith.class)); cards.add(new SetCardInfo("Golgari Findbroker", 175, Rarity.UNCOMMON, mage.cards.g.GolgariFindbroker.class)); - cards.add(new SetCardInfo("Golgari Guildgate", 248, Rarity.COMMON, mage.cards.g.GolgariGuildgate.class)); - cards.add(new SetCardInfo("Golgari Guildgate", 249, Rarity.COMMON, mage.cards.g.GolgariGuildgate.class)); + cards.add(new SetCardInfo("Golgari Guildgate", 248, Rarity.COMMON, mage.cards.g.GolgariGuildgate.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Golgari Guildgate", 249, Rarity.COMMON, mage.cards.g.GolgariGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Golgari Locket", 237, Rarity.COMMON, mage.cards.g.GolgariLocket.class)); cards.add(new SetCardInfo("Golgari Raiders", 130, Rarity.UNCOMMON, mage.cards.g.GolgariRaiders.class)); cards.add(new SetCardInfo("Grappling Sundew", 131, Rarity.UNCOMMON, mage.cards.g.GrapplingSundew.class)); @@ -159,8 +160,8 @@ public final class GuildsOfRavnica extends ExpansionSet { cards.add(new SetCardInfo("Ironshell Beetle", 134, Rarity.COMMON, mage.cards.i.IronshellBeetle.class)); cards.add(new SetCardInfo("Island", 261, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Izoni, Thousand-Eyed", 180, Rarity.RARE, mage.cards.i.IzoniThousandEyed.class)); - cards.add(new SetCardInfo("Izzet Guildgate", 251, Rarity.COMMON, mage.cards.i.IzzetGuildgate.class)); - cards.add(new SetCardInfo("Izzet Guildgate", 252, Rarity.COMMON, mage.cards.i.IzzetGuildgate.class)); + cards.add(new SetCardInfo("Izzet Guildgate", 251, Rarity.COMMON, mage.cards.i.IzzetGuildgate.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Izzet Guildgate", 252, Rarity.COMMON, mage.cards.i.IzzetGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Izzet Locket", 238, Rarity.COMMON, mage.cards.i.IzzetLocket.class)); cards.add(new SetCardInfo("Join Shields", 181, Rarity.UNCOMMON, mage.cards.j.JoinShields.class)); cards.add(new SetCardInfo("Justice Strike", 182, Rarity.UNCOMMON, mage.cards.j.JusticeStrike.class)); @@ -240,8 +241,8 @@ public final class GuildsOfRavnica extends ExpansionSet { cards.add(new SetCardInfo("Runaway Steam-Kin", 115, Rarity.RARE, mage.cards.r.RunawaySteamKin.class)); cards.add(new SetCardInfo("Sacred Foundry", 254, Rarity.RARE, mage.cards.s.SacredFoundry.class)); cards.add(new SetCardInfo("Selective Snare", 53, Rarity.UNCOMMON, mage.cards.s.SelectiveSnare.class)); - cards.add(new SetCardInfo("Selesnya Guildgate", 255, Rarity.COMMON, mage.cards.s.SelesnyaGuildgate.class)); - cards.add(new SetCardInfo("Selesnya Guildgate", 256, Rarity.COMMON, mage.cards.s.SelesnyaGuildgate.class)); + cards.add(new SetCardInfo("Selesnya Guildgate", 255, Rarity.COMMON, mage.cards.s.SelesnyaGuildgate.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Selesnya Guildgate", 256, Rarity.COMMON, mage.cards.s.SelesnyaGuildgate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Selesnya Locket", 240, Rarity.COMMON, mage.cards.s.SelesnyaLocket.class)); cards.add(new SetCardInfo("Severed Strands", 85, Rarity.COMMON, mage.cards.s.SeveredStrands.class)); cards.add(new SetCardInfo("Siege Wurm", 144, Rarity.COMMON, mage.cards.s.SiegeWurm.class)); @@ -342,4 +343,4 @@ public final class GuildsOfRavnica extends ExpansionSet { } return specialCards; } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/HourOfDevastation.java b/Mage.Sets/src/mage/sets/HourOfDevastation.java index 24388aa967..674806cd54 100644 --- a/Mage.Sets/src/mage/sets/HourOfDevastation.java +++ b/Mage.Sets/src/mage/sets/HourOfDevastation.java @@ -101,8 +101,8 @@ public final class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Fervent Paincaster", 91, Rarity.UNCOMMON, mage.cards.f.FerventPaincaster.class)); cards.add(new SetCardInfo("Firebrand Archer", 92, Rarity.COMMON, mage.cards.f.FirebrandArcher.class)); cards.add(new SetCardInfo("Forest", 189, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); - cards.add(new SetCardInfo("Forest", 198, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 199, Rarity.LAND, mage.cards.basiclands.Forest.class)); + cards.add(new SetCardInfo("Forest", 198, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 199, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fraying Sanity", 35, Rarity.RARE, mage.cards.f.FrayingSanity.class)); cards.add(new SetCardInfo("Frilled Sandwalla", 116, Rarity.COMMON, mage.cards.f.FrilledSandwalla.class)); cards.add(new SetCardInfo("Frontline Devastator", 93, Rarity.COMMON, mage.cards.f.FrontlineDevastator.class)); @@ -132,8 +132,8 @@ public final class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Inferno Jet", 99, Rarity.UNCOMMON, mage.cards.i.InfernoJet.class)); cards.add(new SetCardInfo("Ipnu Rivulet", 180, Rarity.UNCOMMON, mage.cards.i.IpnuRivulet.class)); cards.add(new SetCardInfo("Island", 186, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); - cards.add(new SetCardInfo("Island", 192, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 193, Rarity.LAND, mage.cards.basiclands.Island.class)); + cards.add(new SetCardInfo("Island", 192, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 193, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jace's Defeat", 38, Rarity.UNCOMMON, mage.cards.j.JacesDefeat.class)); cards.add(new SetCardInfo("Kefnet's Last Word", 39, Rarity.RARE, mage.cards.k.KefnetsLastWord.class)); cards.add(new SetCardInfo("Khenra Eternal", 66, Rarity.COMMON, mage.cards.k.KhenraEternal.class)); @@ -153,8 +153,8 @@ public final class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Mirage Mirror", 165, Rarity.RARE, mage.cards.m.MirageMirror.class)); cards.add(new SetCardInfo("Moaning Wall", 72, Rarity.COMMON, mage.cards.m.MoaningWall.class)); cards.add(new SetCardInfo("Mountain", 188, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 196, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 197, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Mountain", 196, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 197, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mummy Paramount", 16, Rarity.COMMON, mage.cards.m.MummyParamount.class)); cards.add(new SetCardInfo("Neheb, the Eternal", 104, Rarity.MYTHIC, mage.cards.n.NehebTheEternal.class)); cards.add(new SetCardInfo("Nicol Bolas, God-Pharaoh", 140, Rarity.MYTHIC, mage.cards.n.NicolBolasGodPharaoh.class)); @@ -172,8 +172,8 @@ public final class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Overcome", 125, Rarity.UNCOMMON, mage.cards.o.Overcome.class)); cards.add(new SetCardInfo("Overwhelming Splendor", 19, Rarity.MYTHIC, mage.cards.o.OverwhelmingSplendor.class)); cards.add(new SetCardInfo("Plains", 185, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); - cards.add(new SetCardInfo("Plains", 190, Rarity.LAND, mage.cards.basiclands.Plains.class)); - cards.add(new SetCardInfo("Plains", 191, Rarity.LAND, mage.cards.basiclands.Plains.class)); + cards.add(new SetCardInfo("Plains", 190, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 191, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Pride Sovereign", 126, Rarity.RARE, mage.cards.p.PrideSovereign.class)); cards.add(new SetCardInfo("Proven Combatant", 42, Rarity.COMMON, mage.cards.p.ProvenCombatant.class)); cards.add(new SetCardInfo("Puncturing Blow", 106, Rarity.COMMON, mage.cards.p.PuncturingBlow.class)); @@ -217,8 +217,8 @@ public final class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Supreme Will", 49, Rarity.UNCOMMON, mage.cards.s.SupremeWill.class)); cards.add(new SetCardInfo("Survivors' Encampment", 184, Rarity.COMMON, mage.cards.s.SurvivorsEncampment.class)); cards.add(new SetCardInfo("Swamp", 187, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 194, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 195, Rarity.LAND, mage.cards.basiclands.Swamp.class)); + cards.add(new SetCardInfo("Swamp", 194, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 195, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swarm Intelligence", 50, Rarity.RARE, mage.cards.s.SwarmIntelligence.class)); cards.add(new SetCardInfo("Tenacious Hunter", 136, Rarity.UNCOMMON, mage.cards.t.TenaciousHunter.class)); cards.add(new SetCardInfo("The Locust God", 139, Rarity.MYTHIC, mage.cards.t.TheLocustGod.class)); diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 7ccce7704e..9f9cdc945a 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -10,7 +10,6 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author fireshoes */ public final class Ixalan extends ExpansionSet { @@ -124,10 +123,10 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Fire Shrine Keeper", 144, Rarity.COMMON, mage.cards.f.FireShrineKeeper.class)); cards.add(new SetCardInfo("Firecannon Blast", 145, Rarity.COMMON, mage.cards.f.FirecannonBlast.class)); cards.add(new SetCardInfo("Fleet Swallower", 57, Rarity.RARE, mage.cards.f.FleetSwallower.class)); - cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 279, Rarity.LAND, mage.cards.basiclands.Forest.class)); + cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 279, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Frenzied Raptor", 146, Rarity.COMMON, mage.cards.f.FrenziedRaptor.class)); cards.add(new SetCardInfo("Gilded Sentinel", 239, Rarity.COMMON, mage.cards.g.GildedSentinel.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); @@ -152,10 +151,10 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Imperial Aerosaur", 14, Rarity.UNCOMMON, mage.cards.i.ImperialAerosaur.class)); cards.add(new SetCardInfo("Imperial Lancer", 15, Rarity.UNCOMMON, mage.cards.i.ImperialLancer.class)); cards.add(new SetCardInfo("Inspiring Cleric", 16, Rarity.UNCOMMON, mage.cards.i.InspiringCleric.class)); - cards.add(new SetCardInfo("Island", 264, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 265, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 266, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 267, Rarity.LAND, mage.cards.basiclands.Island.class)); + cards.add(new SetCardInfo("Island", 264, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 265, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 266, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 267, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); cards.add(new SetCardInfo("Ixalli's Diviner", 192, Rarity.COMMON, mage.cards.i.IxallisDiviner.class)); @@ -185,10 +184,10 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mark of the Vampire", 113, Rarity.COMMON, mage.cards.m.MarkOfTheVampire.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Merfolk Branchwalker", 197, Rarity.UNCOMMON, mage.cards.m.MerfolkBranchwalker.class)); - cards.add(new SetCardInfo("Mountain", 272, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 273, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Mountain", 272, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 273, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Navigator's Ruin", 63, Rarity.UNCOMMON, mage.cards.n.NavigatorsRuin.class)); cards.add(new SetCardInfo("New Horizons", 198, Rarity.COMMON, mage.cards.n.NewHorizons.class)); cards.add(new SetCardInfo("Nest Robber", 152, Rarity.COMMON, mage.cards.n.NestRobber.class)); @@ -203,10 +202,10 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Pious Interdiction", 26, Rarity.COMMON, mage.cards.p.PiousInterdiction.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); cards.add(new SetCardInfo("Pirate's Prize", 68, Rarity.COMMON, mage.cards.p.PiratesPrize.class)); - cards.add(new SetCardInfo("Plains", 260, Rarity.LAND, mage.cards.basiclands.Plains.class)); - cards.add(new SetCardInfo("Plains", 261, Rarity.LAND, mage.cards.basiclands.Plains.class)); - cards.add(new SetCardInfo("Plains", 262, Rarity.LAND, mage.cards.basiclands.Plains.class)); - cards.add(new SetCardInfo("Plains", 263, Rarity.LAND, mage.cards.basiclands.Plains.class)); + cards.add(new SetCardInfo("Plains", 260, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 261, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 262, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 263, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Pounce", 200, Rarity.COMMON, mage.cards.p.Pounce.class)); cards.add(new SetCardInfo("Priest of the Wakening Sun", 27, Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); @@ -290,10 +289,10 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); cards.add(new SetCardInfo("Sunrise Seeker", 40, Rarity.COMMON, mage.cards.s.SunriseSeeker.class)); cards.add(new SetCardInfo("Sure Strike", 166, Rarity.COMMON, mage.cards.s.SureStrike.class)); - cards.add(new SetCardInfo("Swamp", 268, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 269, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 270, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class)); + cards.add(new SetCardInfo("Swamp", 268, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 269, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 270, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swashbuckling", 167, Rarity.COMMON, mage.cards.s.Swashbuckling.class)); cards.add(new SetCardInfo("Sword-Point Diplomacy", 126, Rarity.RARE, mage.cards.s.SwordPointDiplomacy.class)); cards.add(new SetCardInfo("Tempest Caller", 86, Rarity.UNCOMMON, mage.cards.t.TempestCaller.class)); @@ -334,4 +333,4 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Wind Strider", 88, Rarity.COMMON, mage.cards.w.WindStrider.class)); cards.add(new SetCardInfo("Woodland Stream", 284, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/MediaInserts.java b/Mage.Sets/src/mage/sets/MediaInserts.java index 2a3f0c2bf9..47d1bd4566 100644 --- a/Mage.Sets/src/mage/sets/MediaInserts.java +++ b/Mage.Sets/src/mage/sets/MediaInserts.java @@ -48,7 +48,7 @@ public final class MediaInserts extends ExpansionSet { cards.add(new SetCardInfo("Celestial Colonnade", 23, Rarity.SPECIAL, mage.cards.c.CelestialColonnade.class)); cards.add(new SetCardInfo("Chandra, Fire of Kaladesh", 997, Rarity.SPECIAL, mage.cards.c.ChandraFireOfKaladesh.class)); cards.add(new SetCardInfo("Chandra, Flamecaller", 175, Rarity.MYTHIC, mage.cards.c.ChandraFlamecaller.class)); - cards.add(new SetCardInfo("Chandra, Pyromaster", 75, Rarity.MYTHIC, mage.cards.c.ChandraPyromaster.class)); + cards.add(new SetCardInfo("Chandra, Pyromaster", 75, Rarity.MYTHIC, mage.cards.c.ChandraPyromaster.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chandra, Pyromaster", 102, Rarity.MYTHIC, mage.cards.c.ChandraPyromaster.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chandra, Roaring Flame", 997, Rarity.SPECIAL, mage.cards.c.ChandraRoaringFlame.class)); cards.add(new SetCardInfo("Chandra, Torch of Defiance", 180, Rarity.MYTHIC, mage.cards.c.ChandraTorchOfDefiance.class)); @@ -113,8 +113,8 @@ public final class MediaInserts extends ExpansionSet { cards.add(new SetCardInfo("Jace, Memory Adept", 73, Rarity.MYTHIC, mage.cards.j.JaceMemoryAdept.class)); cards.add(new SetCardInfo("Jace, Telepath Unbound", 995, Rarity.SPECIAL, mage.cards.j.JaceTelepathUnbound.class)); cards.add(new SetCardInfo("Jace, the Living Guildpact", 100, Rarity.MYTHIC, mage.cards.j.JaceTheLivingGuildpact.class)); - cards.add(new SetCardInfo("Jace, Unraveler of Secrets", 173, Rarity.MYTHIC, mage.cards.j.JaceUnravelerOfSecrets.class)); - cards.add(new SetCardInfo("Jace, Unraveler of Secrets", 178, Rarity.MYTHIC, mage.cards.j.JaceUnravelerOfSecrets.class)); + cards.add(new SetCardInfo("Jace, Unraveler of Secrets", 173, Rarity.MYTHIC, mage.cards.j.JaceUnravelerOfSecrets.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jace, Unraveler of Secrets", 178, Rarity.MYTHIC, mage.cards.j.JaceUnravelerOfSecrets.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jace, Vryn's Prodigy", 995, Rarity.SPECIAL, mage.cards.j.JaceVrynsProdigy.class)); cards.add(new SetCardInfo("Jaya Ballard, Task Mage", 18, Rarity.RARE, mage.cards.j.JayaBallardTaskMage.class)); cards.add(new SetCardInfo("Karametra's Acolyte", 78, Rarity.UNCOMMON, mage.cards.k.KarametrasAcolyte.class)); @@ -127,7 +127,7 @@ public final class MediaInserts extends ExpansionSet { cards.add(new SetCardInfo("Liliana, Death's Majesty", 179, Rarity.MYTHIC, mage.cards.l.LilianaDeathsMajesty.class)); cards.add(new SetCardInfo("Liliana, Defiant Necromancer", 996, Rarity.SPECIAL, mage.cards.l.LilianaDefiantNecromancer.class)); cards.add(new SetCardInfo("Liliana, the Last Hope", 174, Rarity.MYTHIC, mage.cards.l.LilianaTheLastHope.class)); - cards.add(new SetCardInfo("Liliana Vess", 30, Rarity.RARE, mage.cards.l.LilianaVess.class)); + cards.add(new SetCardInfo("Liliana Vess", 30, Rarity.RARE, mage.cards.l.LilianaVess.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Liliana Vess", 101, Rarity.MYTHIC, mage.cards.l.LilianaVess.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Magister of Worth", 86, Rarity.SPECIAL, mage.cards.m.MagisterOfWorth.class)); cards.add(new SetCardInfo("Mana Crypt", 6, Rarity.RARE, mage.cards.m.ManaCrypt.class)); diff --git a/Mage.Sets/src/mage/sets/WPNAndGatewayPromos.java b/Mage.Sets/src/mage/sets/WPNAndGatewayPromos.java index 5f5df11705..2ca40ffc6b 100644 --- a/Mage.Sets/src/mage/sets/WPNAndGatewayPromos.java +++ b/Mage.Sets/src/mage/sets/WPNAndGatewayPromos.java @@ -63,14 +63,14 @@ public final class WPNAndGatewayPromos extends ExpansionSet { cards.add(new SetCardInfo("Vampire Nighthawk", 33, Rarity.RARE, mage.cards.v.VampireNighthawk.class)); // 2010 - https://scryfall.com/sets/pwp10 cards.add(new SetCardInfo("Curse of Wizardry", 47, Rarity.RARE, mage.cards.c.CurseOfWizardry.class)); - cards.add(new SetCardInfo("Fling", 50, Rarity.RARE, mage.cards.f.Fling.class)); + cards.add(new SetCardInfo("Fling", 50, Rarity.RARE, mage.cards.f.Fling.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Golem's Heart", 60, Rarity.RARE, mage.cards.g.GolemsHeart.class)); cards.add(new SetCardInfo("Kor Firewalker", 36, Rarity.RARE, mage.cards.k.KorFirewalker.class)); cards.add(new SetCardInfo("Leatherback Baloth", 37, Rarity.RARE, mage.cards.l.LeatherbackBaloth.class)); cards.add(new SetCardInfo("Pathrazer of Ulamog", 46, Rarity.RARE, mage.cards.p.PathrazerOfUlamog.class)); cards.add(new SetCardInfo("Plague Stinger", 59, Rarity.RARE, mage.cards.p.PlagueStinger.class)); cards.add(new SetCardInfo("Skinrender", 63, Rarity.RARE, mage.cards.s.Skinrender.class)); - cards.add(new SetCardInfo("Sylvan Ranger", 51, Rarity.RARE, mage.cards.s.SylvanRanger.class)); + cards.add(new SetCardInfo("Sylvan Ranger", 51, Rarity.RARE, mage.cards.s.SylvanRanger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Syphon Mind", 40, Rarity.RARE, mage.cards.s.SyphonMind.class)); // 2011 - https://scryfall.com/sets/pwp11 cards.add(new SetCardInfo("Auramancer", 77, Rarity.RARE, mage.cards.a.Auramancer.class)); @@ -78,13 +78,13 @@ public final class WPNAndGatewayPromos extends ExpansionSet { cards.add(new SetCardInfo("Boneyard Wurm", 84, Rarity.RARE, mage.cards.b.BoneyardWurm.class)); cards.add(new SetCardInfo("Circle of Flame", 78, Rarity.RARE, mage.cards.c.CircleOfFlame.class)); cards.add(new SetCardInfo("Curse of the Bloody Tome", 80, Rarity.RARE, mage.cards.c.CurseOfTheBloodyTome.class)); - cards.add(new SetCardInfo("Fling", 69, Rarity.RARE, mage.cards.f.Fling.class)); + cards.add(new SetCardInfo("Fling", 69, Rarity.RARE, mage.cards.f.Fling.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Master's Call", 64, Rarity.RARE, mage.cards.m.MastersCall.class)); cards.add(new SetCardInfo("Maul Splicer", 72, Rarity.RARE, mage.cards.m.MaulSplicer.class)); cards.add(new SetCardInfo("Plague Myr", 65, Rarity.RARE, mage.cards.p.PlagueMyr.class)); cards.add(new SetCardInfo("Shrine of Burning Rage", 73, Rarity.RARE, mage.cards.s.ShrineOfBurningRage.class)); cards.add(new SetCardInfo("Signal Pest", 66, Rarity.RARE, mage.cards.s.SignalPest.class)); - cards.add(new SetCardInfo("Sylvan Ranger", 70, Rarity.RARE, mage.cards.s.SylvanRanger.class)); + cards.add(new SetCardInfo("Sylvan Ranger", 70, Rarity.RARE, mage.cards.s.SylvanRanger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tormented Soul", 76, Rarity.RARE, mage.cards.t.TormentedSoul.class)); cards.add(new SetCardInfo("Vault Skirge", 71, Rarity.RARE, mage.cards.v.VaultSkirge.class)); // 2012 - https://scryfall.com/sets/pwp12 diff --git a/Mage/src/main/java/mage/cards/CardGraphicInfo.java b/Mage/src/main/java/mage/cards/CardGraphicInfo.java index 40d67a23c2..ae9aee3dbb 100644 --- a/Mage/src/main/java/mage/cards/CardGraphicInfo.java +++ b/Mage/src/main/java/mage/cards/CardGraphicInfo.java @@ -6,7 +6,7 @@ public final class CardGraphicInfo { private final ObjectColor frameColor; private final FrameStyle frameStyle; - private final boolean useVariousArt; + private final boolean useVariousArt; // card in set have multiple images (use to store images files) public CardGraphicInfo(FrameStyle frameStyle, boolean useVariousArt) { this(null, frameStyle, useVariousArt); diff --git a/Mage/src/main/java/mage/cards/CardSetInfo.java b/Mage/src/main/java/mage/cards/CardSetInfo.java index 70cf685c05..c6a8ee07e4 100644 --- a/Mage/src/main/java/mage/cards/CardSetInfo.java +++ b/Mage/src/main/java/mage/cards/CardSetInfo.java @@ -21,12 +21,7 @@ public final class CardSetInfo implements Serializable { this.expansionSetCode = expansionSetCode; this.cardNumber = cardNumber; this.rarity = rarity; - if (graphicInfo == null && Rarity.LAND == rarity) { - // Workaround to get images of basic land permanents loaded - this.graphicInfo = ExpansionSet.NON_FULL_USE_VARIOUS; - } else { - this.graphicInfo = graphicInfo; - } + this.graphicInfo = graphicInfo; } public String getName() { From 6bb478c342a549bc3c8b12c267a9dd096e588c11 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 22:32:52 +0400 Subject: [PATCH 018/167] Tests: added many verify tests for sets and cards, e.g.: * check set's class name/file (source code style); * check set's hasBasicLands settings (missing lands in deck generation bug); * check card's UsesVariousArt settings (same image for multi-images card bug); * check card's missing abilities (forgot addAbility call bug); * improved output messages; --- .../mage/test/sets/BoosterGenerationTest.java | 24 +++ .../java/mage/verify/VerifyCardDataTest.java | 191 ++++++++++++++---- 2 files changed, 181 insertions(+), 34 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java b/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java index d282dbc1a9..bfae2666eb 100644 --- a/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java @@ -152,6 +152,30 @@ public class BoosterGenerationTest extends MageTestBase { } } + @Test + public void testColdSnap_BoosterMustHaveOneSnowLand() { + for (int i = 0; i < 10; i++) { + List booster = Coldsnap.getInstance().createBooster(); + assertTrue("coldsnap's booster must contain 1 snow covered land", booster.stream().anyMatch(card -> card.isBasic() && card.getName().startsWith("Snow-Covered "))); + } + } + + @Test + public void testMastersEditionII_BoosterMustHaveOneSnowLand() { + for (int i = 0; i < 10; i++) { + List booster = MastersEditionII.getInstance().createBooster(); + assertTrue("Master Editions II's booster must contain 1 snow covered land", booster.stream().anyMatch(card -> card.isBasic() && card.getName().startsWith("Snow-Covered "))); + } + } + + @Test + public void testBattlebond_BoosterMustHaveOneLand() { + for (int i = 0; i < 10; i++) { + List booster = Coldsnap.getInstance().createBooster(); + assertTrue("battlebond's booster must contain 1 land", booster.stream().anyMatch(card -> card.isBasic() && card.isLand())); + } + } + private static String str(List cards) { StringBuilder sb = new StringBuilder("["); Iterator iterator = cards.iterator(); diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 3882476d58..7dc7c4fa76 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -4,10 +4,12 @@ import mage.ObjectColor; import mage.cards.*; import mage.cards.basiclands.BasicLand; import mage.constants.CardType; +import mage.constants.Constants; import mage.constants.Rarity; import mage.constants.SuperType; import mage.game.permanent.token.Token; import mage.game.permanent.token.TokenImpl; +import mage.util.CardUtil; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -42,12 +44,12 @@ public class VerifyCardDataTest { skipCheckLists.put(listName, new LinkedHashSet<>()); } - private static void skipListAddName(String listName, String name) { - skipCheckLists.get(listName).add(name); + private static void skipListAddName(String listName, String set, String name) { + skipCheckLists.get(listName).add(set + " - " + name); } - private static boolean skipListHaveName(String listName, String name) { - return skipCheckLists.get(listName).contains(name); + private static boolean skipListHaveName(String listName, String set, String name) { + return skipCheckLists.get(listName).contains(set + " - " + name); } static { @@ -55,8 +57,8 @@ public class VerifyCardDataTest { // power-toughness skipListCreate("PT"); - skipListAddName("PT", "Garbage Elemental"); // UST - skipListAddName("PT", "Infinity Elemental"); // UST + skipListAddName("PT", "UST", "Garbage Elemental"); + skipListAddName("PT", "UST", "Infinity Elemental"); // color skipListCreate("COLOR"); @@ -96,15 +98,16 @@ public class VerifyCardDataTest { } private void warn(Card card, String message) { - System.out.println("Warning: " + message + " for " + card.getName() + " (" + card.getExpansionSetCode() + ")"); + outputMessages.add("Warning: " + message + " for " + card.getExpansionSetCode() + " - " + card.getName() + " - " + card.getCardNumber()); } private void fail(Card card, String category, String message) { failed++; - System.out.println("Error: (" + category + ") " + message + " for " + card.getName() + " (" + card.getExpansionSetCode() + ")"); + outputMessages.add("Error: (" + category + ") " + message + " for " + card.getExpansionSetCode() + " - " + card.getName() + " - " + card.getCardNumber()); } private int failed = 0; + private ArrayList outputMessages = new ArrayList<>(); @Test public void verifyCards() throws IOException { @@ -117,8 +120,10 @@ public class VerifyCardDataTest { check(card, tokens); } } + + printMessages(outputMessages); if (failed > 0) { - Assert.fail(failed + " Errors"); + Assert.fail(failed + " errors in verify"); } } @@ -256,12 +261,22 @@ public class VerifyCardDataTest { } } - private void printMessages(Collection list) { - for (String mes : list) { + private void printMessages(Collection list, boolean sorted) { + + ArrayList sortedList = new ArrayList<>(list); + if (sorted) { + sortedList.sort(String::compareTo); + } + + for (String mes : sortedList) { System.out.println(mes); } } + private void printMessages(Collection list) { + printMessages(list, true); + } + private String extractShortClass(Class tokenClass) { String origin = tokenClass.getName(); if (origin.contains("$")) { @@ -273,6 +288,114 @@ public class VerifyCardDataTest { } } + @Test + public void checkMissingSetData() { + Collection errorsList = new ArrayList<>(); + Collection warningsList = new ArrayList<>(); + + Collection sets = Sets.getInstance().values(); + + // 1. wrong set class names + for (ExpansionSet set : sets) { + String className = extractShortClass(set.getClass()); + String needClassName = set.getName() + //.replaceAll("Duel Decks", "") + .replaceAll("&", "And") + .replaceAll(" vs. ", " Vs ") // for more friendly class name generation in logs TODO: replace to CamelCase transform instead custom words + .replaceAll(" the ", " The ") + .replaceAll(" and ", " And ") + .replaceAll(" of ", " Of ") + .replaceAll(" to ", " To ") + .replaceAll(" for ", " For ") + .replaceAll(" into ", " Into ") + .replaceAll(" over ", " Over ") + .replaceAll("[ .+-/:\"']", ""); + + //if (!className.toLowerCase(Locale.ENGLISH).equals(needClassName.toLowerCase(Locale.ENGLISH))) { + if (!className.equals(needClassName)) { + errorsList.add("error, set's class name must be equal to set name: " + + className + " from " + set.getClass().getName() + ", caption: " + set.getName() + ", need name: " + needClassName); + } + } + + // 2. wrong basic lands settings (it's for lands search, not booster construct) + Map skipLandCheck = new HashMap<>(); + for (ExpansionSet set : sets) { + if (skipLandCheck.containsKey(set.getName())) { + continue; + } + + Boolean needLand = set.hasBasicLands(); + Boolean foundedLand = false; + Map foundLandsList = new HashMap<>(); + for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { + if (isBasicLandName(card.getName())) { + foundedLand = true; + int count = foundLandsList.getOrDefault(card.getName(), 0); + foundLandsList.put(card.getName(), count + 1); + } + } + + String landNames = foundLandsList.entrySet().stream() + .map(p -> (p.getKey() + " - " + p.getValue().toString())) + .sorted().collect(Collectors.joining(", ")); + + if (needLand && !foundedLand) { + errorsList.add("error, found set with wrong hasBasicLands - it's true, but haven't land cards: " + set.getCode() + " in " + set.getClass().getName()); + } + + if (!needLand && foundedLand) { + errorsList.add("error, found set with wrong hasBasicLands - it's false, but have land cards: " + set.getCode() + " in " + set.getClass().getName() + ", lands: " + landNames); + } + + // TODO: add test to check num cards (hasBasicLands and numLand > 0) + } + + // TODO: add test to check num cards for rarity (rarityStats > 0 and numRarity > 0) + + printMessages(warningsList); + printMessages(errorsList); + if (errorsList.size() > 0) { + Assert.fail("Founded set errors: " + errorsList.size()); + } + } + + @Test + public void checkMissingCardData() { + Collection errorsList = new ArrayList<>(); + Collection warningsList = new ArrayList<>(); + + Collection sets = Sets.getInstance().values(); + + + // 1. wrong UsesVariousArt settings (set have duplicated card name without that setting -- e.g. cards will have same image) + for (ExpansionSet set : sets) { + + // double names + Map doubleNames = new HashMap<>(); + for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { + int count = doubleNames.getOrDefault(card.getName(), 0); + doubleNames.put(card.getName(), count + 1); + } + + // check + for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { + boolean cardHaveDoubleName = (doubleNames.getOrDefault(card.getName(), 0) > 1); + boolean cardHaveVariousSetting = card.getGraphicInfo() == null ? false : card.getGraphicInfo().getUsesVariousArt(); + + if(cardHaveDoubleName && !cardHaveVariousSetting) { + errorsList.add("error, founded double card names, but UsesVariousArt is not true: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber()); + } + } + } + + printMessages(warningsList); + printMessages(errorsList); + if (errorsList.size() > 0) { + Assert.fail("Founded card errors: " + errorsList.size()); + } + } + @Test @Ignore // TODO: enable test after massive token fixes public void checkMissingTokenData() { @@ -440,7 +563,7 @@ public class VerifyCardDataTest { } private void checkColors(Card card, JsonCard ref) { - if (skipListHaveName("COLOR", card.getName())) { + if (skipListHaveName("COLOR", card.getExpansionSetCode(), card.getName())) { return; } @@ -460,7 +583,7 @@ public class VerifyCardDataTest { } private void checkSubtypes(Card card, JsonCard ref) { - if (skipListHaveName("SUBTYPE", card.getName())) { + if (skipListHaveName("SUBTYPE", card.getExpansionSetCode(), card.getName())) { return; } @@ -469,7 +592,7 @@ public class VerifyCardDataTest { // fix names (e.g. Urza’s to Urza's) if (expected != null && expected.contains("Urza’s")) { expected = new ArrayList<>(expected); - for (ListIterator it = ((List) expected).listIterator(); it.hasNext();) { + for (ListIterator it = ((List) expected).listIterator(); it.hasNext(); ) { if (it.next().equals("Urza’s")) { it.set("Urza's"); } @@ -482,7 +605,7 @@ public class VerifyCardDataTest { } private void checkSupertypes(Card card, JsonCard ref) { - if (skipListHaveName("SUPERTYPE", card.getName())) { + if (skipListHaveName("SUPERTYPE", card.getExpansionSetCode(), card.getName())) { return; } @@ -492,23 +615,8 @@ public class VerifyCardDataTest { } } - private void checkTypes(Card card, JsonCard ref) { - if (skipListHaveName("TYPE", card.getName())) { - return; - } - - Collection expected = ref.types; - List type = new ArrayList<>(); - for (CardType cardType : card.getCardType()) { - type.add(cardType.toString()); - } - if (!eqSet(type, expected)) { - fail(card, "types", type + " != " + expected); - } - } - private void checkMissingAbilities(Card card, JsonCard ref) { - if (skipListHaveName("MISSING_ABILITIES", card.getName())) { + if (skipListHaveName("MISSING_ABILITIES", card.getExpansionSetCode(), card.getName())) { return; } @@ -533,6 +641,21 @@ public class VerifyCardDataTest { } } + private void checkTypes(Card card, JsonCard ref) { + if (skipListHaveName("TYPE", card.getExpansionSetCode(), card.getName())) { + return; + } + + Collection expected = ref.types; + List type = new ArrayList<>(); + for (CardType cardType : card.getCardType()) { + type.add(cardType.toString()); + } + if (!eqSet(type, expected)) { + fail(card, "types", type + " != " + expected); + } + } + private static boolean eqSet(Collection a, Collection b) { if (a == null || a.isEmpty()) { return b == null || b.isEmpty(); @@ -541,7 +664,7 @@ public class VerifyCardDataTest { } private void checkPT(Card card, JsonCard ref) { - if (skipListHaveName("PT", card.getName())) { + if (skipListHaveName("PT", card.getExpansionSetCode(), card.getName())) { return; } @@ -561,7 +684,7 @@ public class VerifyCardDataTest { } private void checkCost(Card card, JsonCard ref) { - if (skipListHaveName("COST", card.getName())) { + if (skipListHaveName("COST", card.getExpansionSetCode(), card.getName())) { return; } @@ -579,7 +702,7 @@ public class VerifyCardDataTest { } private void checkNumbers(Card card, JsonCard ref) { - if (skipListHaveName("NUMBER", card.getName())) { + if (skipListHaveName("NUMBER", card.getExpansionSetCode(), card.getName())) { return; } From 8fd6eb63131e5d9111145a3654a783d87bbbae49 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 22:43:13 +0400 Subject: [PATCH 019/167] Fix merge --- Mage.Sets/src/mage/sets/Battlebond.java | 13 ++++++------- .../test/java/mage/verify/VerifyCardDataTest.java | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 687614bd2d..e01ffafdef 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -5,18 +5,17 @@ import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author TheElk801 */ public final class Battlebond extends ExpansionSet { - + private static final Battlebond instance = new Battlebond(); - + public static Battlebond getInstance() { return instance; } - - + + private Battlebond() { super("Battlebond", "BBD", ExpansionSet.buildDate(2018, 6, 8), SetType.SUPPLEMENTAL); this.blockName = "Battlebond"; @@ -28,7 +27,7 @@ public final class Battlebond extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - + cards.add(new SetCardInfo("Aim High", 189, Rarity.UNCOMMON, mage.cards.a.AimHigh.class)); cards.add(new SetCardInfo("Angel of Retribution", 86, Rarity.UNCOMMON, mage.cards.a.AngelOfRetribution.class)); cards.add(new SetCardInfo("Angelic Chorus", 87, Rarity.RARE, mage.cards.a.AngelicChorus.class)); @@ -286,5 +285,5 @@ public final class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Zndrsplt's Judgment", 43, Rarity.RARE, mage.cards.z.ZndrspltsJudgment.class)); cards.add(new SetCardInfo("Zndrsplt, Eye of Wisdom", 5, Rarity.RARE, mage.cards.z.ZndrspltEyeOfWisdom.class)); } - + } diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 7dc7c4fa76..34869ff85b 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -277,7 +277,7 @@ public class VerifyCardDataTest { printMessages(list, true); } - private String extractShortClass(Class tokenClass) { + private String extractShortClass(Class tokenClass) { String origin = tokenClass.getName(); if (origin.contains("$")) { // inner classes, example: mage.cards.f.FigureOfDestiny$FigureOfDestinyToken3 From 6ad6151be72dde4e921390fc7e851975d326fc0e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 3 Oct 2018 14:50:16 -0400 Subject: [PATCH 020/167] removed rotated cards from standard banlist --- .../src/mage/deck/Standard.java | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java index 2e2098244a..e5f19747e3 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java @@ -1,19 +1,13 @@ package mage.deck; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.List; import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.constants.SetType; +import java.util.*; + /** - * * @author BetaSteward_at_googlemail.com */ public class Standard extends Constructed { @@ -23,13 +17,7 @@ public class Standard extends Constructed { setCodes.addAll(makeLegalSets()); - banned.add("Attune with Aether"); // since 2018-01-15 - banned.add("Aetherworks Marvel"); - banned.add("Felidar Guardian"); banned.add("Rampaging Ferocidon"); // since 2018-01-15 - banned.add("Ramunap Ruins"); // since 2018-01-15 - banned.add("Rogue Refiner"); // since 2018-01-15 - banned.add("Smuggler's Copter"); } private static boolean isFallSet(ExpansionSet set) { From 095ccc397e172551d7a28aaad4f76d7711c36bc9 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 22:53:18 +0400 Subject: [PATCH 021/167] Refactor: corrected class name for set --- .../{GuildKit1.java => GuildsOfRavnicaGuildKits.java} | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) rename Mage.Sets/src/mage/sets/{GuildKit1.java => GuildsOfRavnicaGuildKits.java} (98%) diff --git a/Mage.Sets/src/mage/sets/GuildKit1.java b/Mage.Sets/src/mage/sets/GuildsOfRavnicaGuildKits.java similarity index 98% rename from Mage.Sets/src/mage/sets/GuildKit1.java rename to Mage.Sets/src/mage/sets/GuildsOfRavnicaGuildKits.java index 1909b3b238..b98dc623af 100644 --- a/Mage.Sets/src/mage/sets/GuildKit1.java +++ b/Mage.Sets/src/mage/sets/GuildsOfRavnicaGuildKits.java @@ -8,18 +8,19 @@ import mage.constants.SetType; /** * @author TheElk801 */ -public final class GuildKit1 extends ExpansionSet { +public final class GuildsOfRavnicaGuildKits extends ExpansionSet { - private static final GuildKit1 instance = new GuildKit1(); + private static final GuildsOfRavnicaGuildKits instance = new GuildsOfRavnicaGuildKits(); - public static GuildKit1 getInstance() { + public static GuildsOfRavnicaGuildKits getInstance() { return instance; } - private GuildKit1() { + private GuildsOfRavnicaGuildKits() { super("Guilds of Ravnica Guild Kits", "GK1", ExpansionSet.buildDate(2018, 11, 2), SetType.SUPPLEMENTAL); this.blockName = "Guild Kits"; this.hasBasicLands = true; + cards.add(new SetCardInfo("Abrupt Decay", 57, Rarity.RARE, mage.cards.a.AbruptDecay.class)); cards.add(new SetCardInfo("Advent of the Wurm", 107, Rarity.RARE, mage.cards.a.AdventOfTheWurm.class)); cards.add(new SetCardInfo("Agrus Kos, Wojek Veteran", 83, Rarity.RARE, mage.cards.a.AgrusKosWojekVeteran.class)); From 72d23bfe95f89c1b3f3f4e08c405c162feb4cb7a Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 3 Oct 2018 23:59:51 +0400 Subject: [PATCH 022/167] * UI: deck editor - added cards sorting by rarity (#4414); --- .../deckeditor/table/MageCardComparator.java | 5 ++-- Mage/src/main/java/mage/constants/Rarity.java | 23 +++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/table/MageCardComparator.java b/Mage.Client/src/main/java/mage/client/deckeditor/table/MageCardComparator.java index 1570c99aa7..11a8a9d24b 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/table/MageCardComparator.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/table/MageCardComparator.java @@ -27,6 +27,7 @@ package mage.client.deckeditor.table; import java.util.Comparator; + import mage.cards.MageCard; import mage.view.CardView; @@ -94,8 +95,8 @@ public class MageCardComparator implements Comparator { break; // Rarity case 6: - aCom = a.getRarity().toString(); - bCom = b.getRarity().toString(); + aCom = a.getRarity().getSorting(); + bCom = b.getRarity().getSorting(); break; // Set name case 7: diff --git a/Mage/src/main/java/mage/constants/Rarity.java b/Mage/src/main/java/mage/constants/Rarity.java index b8fbf3259e..2a79d5f368 100644 --- a/Mage/src/main/java/mage/constants/Rarity.java +++ b/Mage/src/main/java/mage/constants/Rarity.java @@ -1,29 +1,30 @@ package mage.constants; /** - * * @author North */ public enum Rarity { - LAND ("Land", "common", "C", 1), - COMMON ("Common", "common", "C", 1), - UNCOMMON ("Uncommon", "uncommon", "U", 2), - RARE ("Rare", "rare", "R", 3), - MYTHIC ("Mythic", "mythic", "M", 3), - SPECIAL ("Special", "special", "Special", 3), - BONUS ("Bonus", "bonus", "Bonus", 3); + LAND("Land", "common", "C", 1, 1), + COMMON("Common", "common", "C", 1, 2), + UNCOMMON("Uncommon", "uncommon", "U", 2, 3), + RARE("Rare", "rare", "R", 3, 4), + MYTHIC("Mythic", "mythic", "M", 3, 5), + SPECIAL("Special", "special", "Special", 3, 6), + BONUS("Bonus", "bonus", "Bonus", 3, 7); private final String text; private final String symbolCode; private final String code; private final int rating; + private final int sorting; - Rarity(String text, String symbolCode, String code, int rating) { + Rarity(String text, String symbolCode, String code, int rating, int sorting) { this.text = text; this.symbolCode = symbolCode; this.code = code; this.rating = rating; + this.sorting = sorting; } @Override @@ -42,4 +43,8 @@ public enum Rarity { public int getRating() { return rating; } + + public int getSorting() { + return sorting; + } } From 4ec40e4fdb420424d5c40c1dcd5bb1d32c9da00a Mon Sep 17 00:00:00 2001 From: L_J Date: Fri, 5 Oct 2018 02:06:44 +0200 Subject: [PATCH 023/167] Implemented Planeshift cards --- .../src/mage/cards/a/AmphibiousKavu.java | 48 ++++++++ .../src/mage/cards/d/DominariasJudgment.java | 63 ++++++++++ Mage.Sets/src/mage/cards/g/GuardDogs.java | 100 ++++++++++++++++ .../src/mage/cards/m/MirrorwoodTreefolk.java | 95 +++++++++++++++ Mage.Sets/src/mage/cards/n/NoxiousVapors.java | 109 ++++++++++++++++++ Mage.Sets/src/mage/sets/Planeshift.java | 22 ++-- 6 files changed, 427 insertions(+), 10 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AmphibiousKavu.java create mode 100644 Mage.Sets/src/mage/cards/d/DominariasJudgment.java create mode 100644 Mage.Sets/src/mage/cards/g/GuardDogs.java create mode 100644 Mage.Sets/src/mage/cards/m/MirrorwoodTreefolk.java create mode 100644 Mage.Sets/src/mage/cards/n/NoxiousVapors.java diff --git a/Mage.Sets/src/mage/cards/a/AmphibiousKavu.java b/Mage.Sets/src/mage/cards/a/AmphibiousKavu.java new file mode 100644 index 0000000000..9548016486 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AmphibiousKavu.java @@ -0,0 +1,48 @@ + +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author L_J + */ +public final class AmphibiousKavu extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blue and/or black creatures"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLUE), new ColorPredicate(ObjectColor.BLACK))); + } + + public AmphibiousKavu(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.subtype.add(SubType.KAVU); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Amphibious Kavu blocks or becomes blocked by one or more blue and/or black creatures, Amphibious Kavu gets +3/+3 until end of turn. + this.addAbility(new BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(new BoostSourceEffect(3, 3, Duration.EndOfTurn), filter, false)); + } + + public AmphibiousKavu(final AmphibiousKavu card) { + super(card); + } + + @Override + public AmphibiousKavu copy() { + return new AmphibiousKavu(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DominariasJudgment.java b/Mage.Sets/src/mage/cards/d/DominariasJudgment.java new file mode 100644 index 0000000000..9da8564410 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DominariasJudgment.java @@ -0,0 +1,63 @@ + +package mage.cards.d; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author L_J + */ +public final class DominariasJudgment extends CardImpl { + + private static final FilterLandPermanent filterPlains = new FilterLandPermanent("Plains"); + private static final FilterLandPermanent filterIsland = new FilterLandPermanent("Island"); + private static final FilterLandPermanent filterSwamp = new FilterLandPermanent("Swamp"); + private static final FilterLandPermanent filterMountain = new FilterLandPermanent("Mountain"); + private static final FilterLandPermanent filterForest = new FilterLandPermanent("Forest"); + + static { + filterPlains.add(new SubtypePredicate(SubType.PLAINS)); + filterIsland.add(new SubtypePredicate(SubType.ISLAND)); + filterSwamp.add(new SubtypePredicate(SubType.SWAMP)); + filterMountain.add(new SubtypePredicate(SubType.MOUNTAIN)); + filterForest.add(new SubtypePredicate(SubType.FOREST)); + } + + public DominariasJudgment(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); + + // Until end of turn, creatures you control gain protection from white if you control a Plains, from blue if you control an Island, from black if you control a Swamp, from red if you control a Mountain, and from green if you control a Forest. + this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new GainAbilityControlledEffect(ProtectionAbility.from(ObjectColor.WHITE), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURE, false), new PermanentsOnTheBattlefieldCondition(filterPlains),"Until end of turn, creatures you control gain protection from white if you control a Plains,")); + this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new GainAbilityControlledEffect(ProtectionAbility.from(ObjectColor.BLUE), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURE, false), new PermanentsOnTheBattlefieldCondition(filterIsland)," from blue if you control an Island,")); + this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new GainAbilityControlledEffect(ProtectionAbility.from(ObjectColor.BLACK), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURE, false), new PermanentsOnTheBattlefieldCondition(filterSwamp)," from black if you control a Swamp,")); + this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new GainAbilityControlledEffect(ProtectionAbility.from(ObjectColor.RED), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURE, false), new PermanentsOnTheBattlefieldCondition(filterMountain)," from red if you control a Mountain,")); + this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new GainAbilityControlledEffect(ProtectionAbility.from(ObjectColor.GREEN), Duration.EndOfTurn, + StaticFilters.FILTER_PERMANENT_CREATURE, false), new PermanentsOnTheBattlefieldCondition(filterForest)," and from green if you control a Forest")); + } + + public DominariasJudgment(final DominariasJudgment card) { + super(card); + } + + @Override + public DominariasJudgment copy() { + return new DominariasJudgment(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GuardDogs.java b/Mage.Sets/src/mage/cards/g/GuardDogs.java new file mode 100644 index 0000000000..6101684b23 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GuardDogs.java @@ -0,0 +1,100 @@ + +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author L_J + */ +public final class GuardDogs extends CardImpl { + + public GuardDogs(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + this.subtype.add(SubType.HOUND); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {2}{W}, {T}: Choose a permanent you control. Prevent all combat damage target creature would deal this turn if it shares a color with that permanent. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GuardDogsEffect(), new ManaCostsImpl("{2}{W}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public GuardDogs(final GuardDogs card) { + super(card); + } + + @Override + public GuardDogs copy() { + return new GuardDogs(this); + } +} + +class GuardDogsEffect extends PreventionEffectImpl { + + private TargetControlledPermanent controlledTarget; + + public GuardDogsEffect() { + super(Duration.EndOfTurn, Integer.MAX_VALUE, true); + this.staticText = "Choose a permanent you control. Prevent all combat damage target creature would deal this turn if it shares a color with that permanent"; + } + + public GuardDogsEffect(final GuardDogsEffect effect) { + super(effect); + } + + + @Override + public void init(Ability source, Game game) { + this.controlledTarget = new TargetControlledPermanent(); + this.controlledTarget.setNotTarget(true); + this.controlledTarget.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), game); + super.init(source, game); + } + + + @Override + public GuardDogsEffect copy() { + return new GuardDogsEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (!this.used && super.applies(event, source, game)) { + MageObject mageObject = game.getObject(event.getSourceId()); + if (mageObject != null + && controlledTarget.getFirstTarget() != null) { + Permanent permanent = game.getPermanentOrLKIBattlefield(controlledTarget.getFirstTarget()); + Permanent targetPermanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); + if (permanent != null + && targetPermanent != null + && this.getTargetPointer().getTargets(game, source).contains(event.getSourceId()) + && permanent.getColor(game).shares(targetPermanent.getColor(game))) { + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/m/MirrorwoodTreefolk.java b/Mage.Sets/src/mage/cards/m/MirrorwoodTreefolk.java new file mode 100644 index 0000000000..c648d36d5a --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MirrorwoodTreefolk.java @@ -0,0 +1,95 @@ + +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.RedirectionEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetAnyTarget; + +/** + * + * @author LevelX2 & L_J + */ +public final class MirrorwoodTreefolk extends CardImpl { + + public MirrorwoodTreefolk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.subtype.add(SubType.TREEFOLK); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // {2}{R}{W}: The next time damage would be dealt to Mirrorwood Treefolk this turn, that damage is dealt to any target instead. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MirrorwoodTreefolkEffect(), new ManaCostsImpl("{2}{R}{W}")); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + } + + public MirrorwoodTreefolk(final MirrorwoodTreefolk card) { + super(card); + } + + @Override + public MirrorwoodTreefolk copy() { + return new MirrorwoodTreefolk(this); + } +} + +class MirrorwoodTreefolkEffect extends RedirectionEffect { + + protected MageObjectReference redirectToObject; + + public MirrorwoodTreefolkEffect() { + super(Duration.EndOfTurn, Integer.MAX_VALUE, UsageType.ONE_USAGE_ABSOLUTE); + staticText = "The next time damage would be dealt to {this} this turn, that damage is dealt to any target instead"; + } + + public MirrorwoodTreefolkEffect(final MirrorwoodTreefolkEffect effect) { + super(effect); + this.redirectToObject = effect.redirectToObject; + } + + @Override + public MirrorwoodTreefolkEffect copy() { + return new MirrorwoodTreefolkEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + redirectToObject = new MageObjectReference(source.getTargets().get(0).getFirstTarget(), game); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_CREATURE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getTargetId().equals(source.getSourceId())) { + if (redirectToObject.equals(new MageObjectReference(source.getTargets().get(0).getFirstTarget(), game))) { + redirectTarget = source.getTargets().get(0); + return true; + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + +} diff --git a/Mage.Sets/src/mage/cards/n/NoxiousVapors.java b/Mage.Sets/src/mage/cards/n/NoxiousVapors.java new file mode 100644 index 0000000000..1e67b13521 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NoxiousVapors.java @@ -0,0 +1,109 @@ + +package mage.cards.n; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.ObjectColor; +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.FilterCard; +import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; + +/** + * + * @author L_J + */ +public final class NoxiousVapors extends CardImpl { + + public NoxiousVapors(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{B}"); + + // Each player reveals their hand, chooses one card of each color from it, then discards all other nonland cards. + this.getSpellAbility().addEffect(new NoxiousVaporsEffect()); + + } + + public NoxiousVapors(final NoxiousVapors card) { + super(card); + } + + @Override + public NoxiousVapors copy() { + return new NoxiousVapors(this); + } +} + +class NoxiousVaporsEffect extends OneShotEffect { + + private static final FilterNonlandCard filter = new FilterNonlandCard(); + + public NoxiousVaporsEffect() { + super(Outcome.Benefit); + this.staticText = "Each player reveals their hand, chooses one card of each color from it, then discards all other nonland cards"; + } + + public NoxiousVaporsEffect(final NoxiousVaporsEffect effect) { + super(effect); + } + + @Override + public NoxiousVaporsEffect copy() { + return new NoxiousVaporsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + player.revealCards(player.getName() + "'s hand", player.getHand(), game); + } + } + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Set chosenCards = new HashSet<>(); + chooseCardForColor(ObjectColor.WHITE, chosenCards, player, game, source); + chooseCardForColor(ObjectColor.BLUE, chosenCards, player, game, source); + chooseCardForColor(ObjectColor.BLACK, chosenCards, player, game, source); + chooseCardForColor(ObjectColor.RED, chosenCards, player, game, source); + chooseCardForColor(ObjectColor.GREEN, chosenCards, player, game, source); + + Set cards = player.getHand().getCards(game); + for (Card card : cards) { + if (card != null && !chosenCards.contains(card) && filter.match(card, game)) { + player.discard(card, source, game); + } + } + } + } + return true; + } + return false; + } + + private void chooseCardForColor(ObjectColor color, Set chosenCards, Player player, Game game, Ability source) { + FilterCard filter = new FilterCard(); + filter.add(new ColorPredicate(color)); + TargetCardInHand target = new TargetCardInHand(filter); + if (player.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + chosenCards.add(card); + } + } + } +} diff --git a/Mage.Sets/src/mage/sets/Planeshift.java b/Mage.Sets/src/mage/sets/Planeshift.java index eec82b0af4..f56f1e92fe 100644 --- a/Mage.Sets/src/mage/sets/Planeshift.java +++ b/Mage.Sets/src/mage/sets/Planeshift.java @@ -2,14 +2,10 @@ package mage.sets; import mage.cards.ExpansionSet; -import mage.cards.e.ErtaiTheCorrupted; -import mage.cards.s.SkyshipWeatherlight; -import mage.cards.t.TahngarthTalruumHero; import mage.constants.Rarity; import mage.constants.SetType; /** - * * @author North */ public final class Planeshift extends ExpansionSet { @@ -31,8 +27,10 @@ public final class Planeshift extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Allied Strategies", 20, Rarity.UNCOMMON, mage.cards.a.AlliedStrategies.class)); cards.add(new SetCardInfo("Alpha Kavu", 77, Rarity.UNCOMMON, mage.cards.a.AlphaKavu.class)); + cards.add(new SetCardInfo("Amphibious Kavu", 78, Rarity.COMMON, mage.cards.a.AmphibiousKavu.class)); cards.add(new SetCardInfo("Ancient Spider", 96, Rarity.RARE, mage.cards.a.AncientSpider.class)); cards.add(new SetCardInfo("Arctic Merfolk", 21, Rarity.COMMON, mage.cards.a.ArcticMerfolk.class)); cards.add(new SetCardInfo("Aura Blast", 1, Rarity.COMMON, mage.cards.a.AuraBlast.class)); @@ -53,6 +51,7 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Destructive Flow", 102, Rarity.RARE, mage.cards.d.DestructiveFlow.class)); cards.add(new SetCardInfo("Diabolic Intent", 42, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); cards.add(new SetCardInfo("Disciple of Kangee", 3, Rarity.COMMON, mage.cards.d.DiscipleOfKangee.class)); + cards.add(new SetCardInfo("Dominaria's Judgment", 4, Rarity.RARE, mage.cards.d.DominariasJudgment.class)); cards.add(new SetCardInfo("Doomsday Specter", 103, Rarity.RARE, mage.cards.d.DoomsdaySpecter.class)); cards.add(new SetCardInfo("Draco", 131, Rarity.RARE, mage.cards.d.Draco.class)); cards.add(new SetCardInfo("Dralnu's Crusade", 104, Rarity.RARE, mage.cards.d.DralnusCrusade.class)); @@ -61,8 +60,8 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Dromar's Charm", 105, Rarity.UNCOMMON, mage.cards.d.DromarsCharm.class)); cards.add(new SetCardInfo("Eladamri's Call", 106, Rarity.RARE, mage.cards.e.EladamrisCall.class)); cards.add(new SetCardInfo("Ertai's Trickery", 24, Rarity.UNCOMMON, mage.cards.e.ErtaisTrickery.class)); - cards.add(new SetCardInfo("Ertai, the Corrupted", "107a", Rarity.RARE, ErtaiTheCorrupted.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ertai, the Corrupted", "107b", Rarity.RARE, ErtaiTheCorrupted.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ertai, the Corrupted", "107a", Rarity.RARE, mage.cards.e.ErtaiTheCorrupted.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ertai, the Corrupted", "107b", Rarity.RARE, mage.cards.e.ErtaiTheCorrupted.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Escape Routes", 25, Rarity.COMMON, mage.cards.e.EscapeRoutes.class)); cards.add(new SetCardInfo("Exotic Disease", 43, Rarity.UNCOMMON, mage.cards.e.ExoticDisease.class)); cards.add(new SetCardInfo("Falling Timber", 79, Rarity.COMMON, mage.cards.f.FallingTimber.class)); @@ -74,6 +73,7 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Gainsay", 26, Rarity.UNCOMMON, mage.cards.g.Gainsay.class)); cards.add(new SetCardInfo("Gerrard's Command", 109, Rarity.COMMON, mage.cards.g.GerrardsCommand.class)); cards.add(new SetCardInfo("Goblin Game", 61, Rarity.RARE, mage.cards.g.GoblinGame.class)); + cards.add(new SetCardInfo("Guard Dogs", 5, Rarity.UNCOMMON, mage.cards.g.GuardDogs.class)); cards.add(new SetCardInfo("Heroic Defiance", 6, Rarity.COMMON, mage.cards.h.HeroicDefiance.class)); cards.add(new SetCardInfo("Hobble", 7, Rarity.COMMON, mage.cards.h.Hobble.class)); cards.add(new SetCardInfo("Honorable Scout", 8, Rarity.COMMON, mage.cards.h.HonorableScout.class)); @@ -98,6 +98,7 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Meddling Mage", 116, Rarity.RARE, mage.cards.m.MeddlingMage.class)); cards.add(new SetCardInfo("Meteor Crater", 140, Rarity.RARE, mage.cards.m.MeteorCrater.class)); cards.add(new SetCardInfo("Mire Kavu", 67, Rarity.COMMON, mage.cards.m.MireKavu.class)); + cards.add(new SetCardInfo("Mirrorwood Treefolk", 83, Rarity.UNCOMMON, mage.cards.m.MirrorwoodTreefolk.class)); cards.add(new SetCardInfo("Mogg Jailer", 68, Rarity.UNCOMMON, mage.cards.m.MoggJailer.class)); cards.add(new SetCardInfo("Mogg Sentry", 69, Rarity.RARE, mage.cards.m.MoggSentry.class)); cards.add(new SetCardInfo("Morgue Toad", 46, Rarity.COMMON, mage.cards.m.MorgueToad.class)); @@ -106,6 +107,7 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Nemata, Grove Guardian", 85, Rarity.RARE, mage.cards.n.NemataGroveGuardian.class)); cards.add(new SetCardInfo("Nightscape Battlemage", 47, Rarity.UNCOMMON, mage.cards.n.NightscapeBattlemage.class)); cards.add(new SetCardInfo("Nightscape Familiar", 48, Rarity.COMMON, mage.cards.n.NightscapeFamiliar.class)); + cards.add(new SetCardInfo("Noxious Vapors", 49, Rarity.UNCOMMON, mage.cards.n.NoxiousVapors.class)); cards.add(new SetCardInfo("Orim's Chant", 11, Rarity.RARE, mage.cards.o.OrimsChant.class)); cards.add(new SetCardInfo("Phyrexian Bloodstock", 50, Rarity.COMMON, mage.cards.p.PhyrexianBloodstock.class)); cards.add(new SetCardInfo("Phyrexian Scuta", 51, Rarity.RARE, mage.cards.p.PhyrexianScuta.class)); @@ -139,8 +141,8 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Singe", 71, Rarity.COMMON, mage.cards.s.Singe.class)); cards.add(new SetCardInfo("Sinister Strength", 54, Rarity.COMMON, mage.cards.s.SinisterStrength.class)); cards.add(new SetCardInfo("Sisay's Ingenuity", 33, Rarity.COMMON, mage.cards.s.SisaysIngenuity.class)); - cards.add(new SetCardInfo("Skyship Weatherlight", "133a", Rarity.RARE, SkyshipWeatherlight.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Skyship Weatherlight", "133b", Rarity.RARE, SkyshipWeatherlight.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Skyship Weatherlight", "133a", Rarity.RARE, mage.cards.s.SkyshipWeatherlight.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Skyship Weatherlight", "133b", Rarity.RARE, mage.cards.s.SkyshipWeatherlight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Skyshroud Blessing", 92, Rarity.UNCOMMON, mage.cards.s.SkyshroudBlessing.class)); cards.add(new SetCardInfo("Slay", 55, Rarity.UNCOMMON, mage.cards.s.Slay.class)); cards.add(new SetCardInfo("Sleeping Potion", 34, Rarity.COMMON, mage.cards.s.SleepingPotion.class)); @@ -157,8 +159,8 @@ public final class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Sunscape Battlemage", 16, Rarity.UNCOMMON, mage.cards.s.SunscapeBattlemage.class)); cards.add(new SetCardInfo("Sunscape Familiar", 17, Rarity.COMMON, mage.cards.s.SunscapeFamiliar.class)); cards.add(new SetCardInfo("Surprise Deployment", 18, Rarity.UNCOMMON, mage.cards.s.SurpriseDeployment.class)); - cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74a", Rarity.RARE, TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74b", Rarity.RARE, TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74a", Rarity.RARE, mage.cards.t.TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74b", Rarity.RARE, mage.cards.t.TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Terminal Moraine", 142, Rarity.UNCOMMON, mage.cards.t.TerminalMoraine.class)); cards.add(new SetCardInfo("Terminate", 128, Rarity.COMMON, mage.cards.t.Terminate.class)); cards.add(new SetCardInfo("Thornscape Battlemage", 94, Rarity.UNCOMMON, mage.cards.t.ThornscapeBattlemage.class)); From 01235ebe291a66bf21d9c7b372cf7788548f2082 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 17:12:00 +0400 Subject: [PATCH 024/167] Missing comments --- Mage.Sets/src/mage/cards/b/BoarUmbra.java | 3 +++ Mage.Sets/src/mage/cards/c/CrabUmbra.java | 7 +++++-- Mage.Sets/src/mage/cards/d/DrakeUmbra.java | 7 +++++-- Mage.Sets/src/mage/cards/e/EelUmbra.java | 10 +++++++--- Mage.Sets/src/mage/cards/e/ElandUmbra.java | 8 +++++--- Mage.Sets/src/mage/cards/m/MammothUmbra.java | 7 +++++-- .../main/java/mage/game/permanent/token/MaskToken.java | 6 +++--- 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BoarUmbra.java b/Mage.Sets/src/mage/cards/b/BoarUmbra.java index c161a7a1ca..5e40bb1e6a 100644 --- a/Mage.Sets/src/mage/cards/b/BoarUmbra.java +++ b/Mage.Sets/src/mage/cards/b/BoarUmbra.java @@ -31,8 +31,11 @@ public final class BoarUmbra extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature gets +3/+3. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield))); + + // Totem armor this.addAbility(new TotemArmorAbility()); } diff --git a/Mage.Sets/src/mage/cards/c/CrabUmbra.java b/Mage.Sets/src/mage/cards/c/CrabUmbra.java index 86f5d56cf7..da173d8340 100644 --- a/Mage.Sets/src/mage/cards/c/CrabUmbra.java +++ b/Mage.Sets/src/mage/cards/c/CrabUmbra.java @@ -2,6 +2,7 @@ package mage.cards.c; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -19,13 +20,12 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; /** - * * @author Loki */ public final class CrabUmbra extends CardImpl { public CrabUmbra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); this.subtype.add(SubType.AURA); @@ -35,8 +35,11 @@ public final class CrabUmbra extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // {2}{U}: Untap enchanted creature. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapEnchantedEffect(), new ManaCostsImpl("{2}{U}"))); + + // Totem armor this.addAbility(new TotemArmorAbility()); } diff --git a/Mage.Sets/src/mage/cards/d/DrakeUmbra.java b/Mage.Sets/src/mage/cards/d/DrakeUmbra.java index 299d7b0737..8a124d093f 100644 --- a/Mage.Sets/src/mage/cards/d/DrakeUmbra.java +++ b/Mage.Sets/src/mage/cards/d/DrakeUmbra.java @@ -2,6 +2,7 @@ package mage.cards.d; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; @@ -17,13 +18,12 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; /** - * * @author Loki */ public final class DrakeUmbra extends CardImpl { public DrakeUmbra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}"); this.subtype.add(SubType.AURA); @@ -33,9 +33,12 @@ public final class DrakeUmbra extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature gets +3/+3 and has flying. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA))); + + // Totem armor this.addAbility(new TotemArmorAbility()); } diff --git a/Mage.Sets/src/mage/cards/e/EelUmbra.java b/Mage.Sets/src/mage/cards/e/EelUmbra.java index d0d69cce3d..7438c42029 100644 --- a/Mage.Sets/src/mage/cards/e/EelUmbra.java +++ b/Mage.Sets/src/mage/cards/e/EelUmbra.java @@ -2,6 +2,7 @@ package mage.cards.e; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; @@ -20,25 +21,28 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; /** - * * @author Loki */ public final class EelUmbra extends CardImpl { public EelUmbra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); this.subtype.add(SubType.AURA); - + // Flash this.addAbility(FlashAbility.getInstance()); + // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature gets +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield))); + + // Totem armor this.addAbility(new TotemArmorAbility()); } diff --git a/Mage.Sets/src/mage/cards/e/ElandUmbra.java b/Mage.Sets/src/mage/cards/e/ElandUmbra.java index 86a2c8be49..1cbee9cbfa 100644 --- a/Mage.Sets/src/mage/cards/e/ElandUmbra.java +++ b/Mage.Sets/src/mage/cards/e/ElandUmbra.java @@ -2,6 +2,7 @@ package mage.cards.e; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; @@ -19,24 +20,25 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; /** - * * @author Loki */ public final class ElandUmbra extends CardImpl { public ElandUmbra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); this.subtype.add(SubType.AURA); - // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature gets +0/+4. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(0, 4, Duration.WhileOnBattlefield))); + + // Totem armor this.addAbility(new TotemArmorAbility()); } diff --git a/Mage.Sets/src/mage/cards/m/MammothUmbra.java b/Mage.Sets/src/mage/cards/m/MammothUmbra.java index 4b67b0e72c..1734366642 100644 --- a/Mage.Sets/src/mage/cards/m/MammothUmbra.java +++ b/Mage.Sets/src/mage/cards/m/MammothUmbra.java @@ -2,6 +2,7 @@ package mage.cards.m; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; @@ -17,13 +18,12 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; /** - * * @author Loki */ public final class MammothUmbra extends CardImpl { public MammothUmbra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}"); this.subtype.add(SubType.AURA); @@ -33,9 +33,12 @@ public final class MammothUmbra extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // Enchanted creature gets +3/+3 and has vigilance. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA))); + + // Totem armor this.addAbility(new TotemArmorAbility()); } diff --git a/Mage/src/main/java/mage/game/permanent/token/MaskToken.java b/Mage/src/main/java/mage/game/permanent/token/MaskToken.java index 662ee9e060..fd1619f995 100644 --- a/Mage/src/main/java/mage/game/permanent/token/MaskToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/MaskToken.java @@ -10,7 +10,6 @@ import mage.constants.SubType; import mage.target.TargetPermanent; /** - * * @author TheElk801 */ public final class MaskToken extends TokenImpl { @@ -18,8 +17,8 @@ public final class MaskToken extends TokenImpl { public MaskToken() { super( "Mask", "white Aura enchantment token named Mask " - + "attached to another target permanent. " - + "The token has enchant permanent and totem armor." + + "attached to another target permanent. " + + "The token has enchant permanent and totem armor." ); cardType.add(CardType.ENCHANTMENT); color.setWhite(true); @@ -31,6 +30,7 @@ public final class MaskToken extends TokenImpl { ability.addEffect(new AttachEffect(Outcome.BoostCreature)); this.addAbility(ability); + // Totem armor this.addAbility(new TotemArmorAbility()); } From 2b411b9c92b71c64f34941520f21d84531977c05 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 17:13:27 +0400 Subject: [PATCH 025/167] [ANA] - implemented Angelic Reward --- Mage.Sets/src/mage/cards/a/AngelicReward.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AngelicReward.java diff --git a/Mage.Sets/src/mage/cards/a/AngelicReward.java b/Mage.Sets/src/mage/cards/a/AngelicReward.java new file mode 100644 index 0000000000..dce1309e72 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AngelicReward.java @@ -0,0 +1,53 @@ +package mage.cards.a; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TotemArmorAbility; +import mage.abilities.mana.AnyColorManaAbility; +import mage.abilities.mana.WhiteManaAbility; +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 JayDi85 + */ + +public final class AngelicReward extends CardImpl { + + public AngelicReward(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}"); + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +3/+3 and has flying. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA))); + } + + public AngelicReward(final AngelicReward card) { + super(card); + } + + @Override + public AngelicReward copy() { + return new AngelicReward(this); + } +} From e9fa44f3545ac4987010cf6840956e4e5c09fda7 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 17:22:22 +0400 Subject: [PATCH 026/167] [ANA] - implemented Blinding Radiance --- .../src/mage/cards/b/BlindingRadiance.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BlindingRadiance.java diff --git a/Mage.Sets/src/mage/cards/b/BlindingRadiance.java b/Mage.Sets/src/mage/cards/b/BlindingRadiance.java new file mode 100644 index 0000000000..2ef6ef3039 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlindingRadiance.java @@ -0,0 +1,40 @@ +package mage.cards.b; + +import mage.abilities.effects.common.TapAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterOpponentsCreaturePermanent; +import mage.filter.predicate.mageobject.ToughnessPredicate; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class BlindingRadiance extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterOpponentsCreaturePermanent("creatures your opponents control with toughness 2 or less"); + static { + filter.add(new ToughnessPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public BlindingRadiance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}"); + + // Tap all creatures your opponents control with toughness 2 or less. + TapAllEffect effect = new TapAllEffect(filter); + this.getSpellAbility().addEffect(effect); + } + + public BlindingRadiance(final BlindingRadiance card) { + super(card); + } + + @Override + public BlindingRadiance copy() { + return new BlindingRadiance(this); + } +} \ No newline at end of file From be55ba19eb006f09750658055f364a9820011d47 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 17:59:47 +0400 Subject: [PATCH 027/167] [ANA] - implemented Cruel Cut --- Mage.Sets/src/mage/cards/c/CruelCut.java | 42 ++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CruelCut.java diff --git a/Mage.Sets/src/mage/cards/c/CruelCut.java b/Mage.Sets/src/mage/cards/c/CruelCut.java new file mode 100644 index 0000000000..267732f89f --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CruelCut.java @@ -0,0 +1,42 @@ +package mage.cards.c; + +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author JayDi85 + */ + +public final class CruelCut extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power 2 or less"); + + static { + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public CruelCut(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); + + // Destroy target creature with power 2 or less. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public CruelCut(final CruelCut card) { + super(card); + } + + @Override + public CruelCut copy() { + return new CruelCut(this); + } +} From cdf639ae651a39fe7643dc67a091b573d682687f Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:03:20 +0400 Subject: [PATCH 028/167] [ANA] - implemented Feral Roar --- Mage.Sets/src/mage/cards/f/FeralRoar.java | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FeralRoar.java diff --git a/Mage.Sets/src/mage/cards/f/FeralRoar.java b/Mage.Sets/src/mage/cards/f/FeralRoar.java new file mode 100644 index 0000000000..46598d12af --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FeralRoar.java @@ -0,0 +1,33 @@ +package mage.cards.f; + +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class FeralRoar extends CardImpl { + + public FeralRoar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}"); + + // Target creature gets +4/+4 until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect(4, 4, Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public FeralRoar(final FeralRoar card) { + super(card); + } + + @Override + public FeralRoar copy() { + return new FeralRoar(this); + } +} \ No newline at end of file From aeab7a6d8f2148c8fbe4fba8cf3835137caaba97 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:06:13 +0400 Subject: [PATCH 029/167] [ANA] - implemented Goblin Bruiser --- Mage.Sets/src/mage/cards/g/GoblinBruiser.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinBruiser.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinBruiser.java b/Mage.Sets/src/mage/cards/g/GoblinBruiser.java new file mode 100644 index 0000000000..ab4b7acfe0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinBruiser.java @@ -0,0 +1,33 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class GoblinBruiser extends CardImpl { + + public GoblinBruiser(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARRIOR); + + this.power = new MageInt(3); + this.toughness = new MageInt(3); + } + + public GoblinBruiser(final GoblinBruiser card) { + super(card); + } + + @Override + public GoblinBruiser copy() { + return new GoblinBruiser(this); + } +} From 7dfebc98f22eefe935eb0913ccbe8ec65ae9e2b7 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:10:11 +0400 Subject: [PATCH 030/167] [ANA] - implemented Goblin Gang Leader --- .../src/mage/cards/g/GoblinGangLeader.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinGangLeader.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinGangLeader.java b/Mage.Sets/src/mage/cards/g/GoblinGangLeader.java new file mode 100644 index 0000000000..c39be8d432 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinGangLeader.java @@ -0,0 +1,39 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.GoblinToken; + +import java.util.UUID; + +/** + * + * @author JayDi85 + */ +public final class GoblinGangLeader extends CardImpl { + + public GoblinGangLeader(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + this.subtype.add(SubType.GOBLIN, SubType.WARRIOR); + + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Goblin Gang Leader enters the battlefield, create two 1/1 red Goblin creature tokens. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoblinToken(), 2))); + } + + public GoblinGangLeader(final GoblinGangLeader card) { + super(card); + } + + @Override + public GoblinGangLeader copy() { + return new GoblinGangLeader(this); + } +} From 0181bf4f4176a82d90f825bb5f60e1ce541a301b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:17:15 +0400 Subject: [PATCH 031/167] [ANA] - added goblin token --- Mage.Client/src/main/resources/card-pictures-tok.txt | 1 + Mage/src/main/java/mage/game/permanent/token/GoblinToken.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Client/src/main/resources/card-pictures-tok.txt b/Mage.Client/src/main/resources/card-pictures-tok.txt index 0598855512..61e9eef56c 100644 --- a/Mage.Client/src/main/resources/card-pictures-tok.txt +++ b/Mage.Client/src/main/resources/card-pictures-tok.txt @@ -105,6 +105,7 @@ |Generate|PLANE:PCA|Plane - Truga Jungle|||TrugaJunglePlane| |Generate|PLANE:PCA|Plane - Turri Island|||TurriIslandPlane| |Generate|PLANE:PCA|Plane - Undercity Reaches|||UndercityReachesPlane| +|Generate|TOK:ANA|Goblin|||GoblinToken| |Generate|TOK:PCA|Eldrazi|||EldraziAnnihilatorToken| |Generate|TOK:10E|Ape|||PongifyApeToken| |Generate|TOK:10E|Dragon|||DragonToken2| diff --git a/Mage/src/main/java/mage/game/permanent/token/GoblinToken.java b/Mage/src/main/java/mage/game/permanent/token/GoblinToken.java index e59b7f70df..79a3a2236d 100644 --- a/Mage/src/main/java/mage/game/permanent/token/GoblinToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/GoblinToken.java @@ -20,7 +20,7 @@ public final class GoblinToken extends TokenImpl { static { tokenImageSets.addAll(Arrays.asList("10E", "ALA", "SOM", "M10", "NPH", "M13", "RTR", "MMA", "M15", "C14", "KTK", "EVG", "DTK", "ORI", "DDG", "DDN", "DD3EVG", "MM2", - "MM3", "EMA", "C16", "DOM")); + "MM3", "EMA", "C16", "DOM", "ANA")); } public GoblinToken(boolean withHaste) { From 088155dee42d6f40f873198e5131d4ac2017349e Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:25:36 +0400 Subject: [PATCH 032/167] [ANA] - implemented Inspiring Commander --- .../src/mage/cards/i/InspiringCommander.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/InspiringCommander.java diff --git a/Mage.Sets/src/mage/cards/i/InspiringCommander.java b/Mage.Sets/src/mage/cards/i/InspiringCommander.java new file mode 100644 index 0000000000..a4760c20d1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InspiringCommander.java @@ -0,0 +1,59 @@ +package mage.cards.i; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class InspiringCommander extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("another creature with power 2 or less"); + + static { + filter.add(new AnotherPredicate()); + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public InspiringCommander(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Whenever another creature with power 2 or less enters the battlefield under your control, you gain 1 life and draw a card. + Effect effect1 = new GainLifeEffect(1); + Effect effect2 = new DrawCardSourceControllerEffect(1); + Ability ability = new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, effect1, filter, false); + ability.addEffect(effect2); + this.addAbility(ability); + } + + public InspiringCommander(final InspiringCommander card) { + super(card); + } + + @Override + public InspiringCommander copy() { + return new InspiringCommander(this); + } +} From da841f87e85c6654dd1dd3116b8d649ad4764358 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:28:41 +0400 Subject: [PATCH 033/167] [ANA] - implemented Nimble Pilferer --- .../src/mage/cards/n/NimblePilferer.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/n/NimblePilferer.java diff --git a/Mage.Sets/src/mage/cards/n/NimblePilferer.java b/Mage.Sets/src/mage/cards/n/NimblePilferer.java new file mode 100644 index 0000000000..bbd383b664 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NimblePilferer.java @@ -0,0 +1,36 @@ +package mage.cards.n; + +import mage.MageInt; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class NimblePilferer extends CardImpl { + + public NimblePilferer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ROGUE); + + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + this.addAbility(FlashAbility.getInstance()); + } + + public NimblePilferer(final NimblePilferer card) { + super(card); + } + + @Override + public NimblePilferer copy() { + return new NimblePilferer(this); + } +} From 5db3a46827e6c352e65e6a5b8ca6eb1594ad9d72 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:35:16 +0400 Subject: [PATCH 034/167] [ANA] - implemented Ogre Painbringer --- .../src/mage/cards/o/OgrePainbringer.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OgrePainbringer.java diff --git a/Mage.Sets/src/mage/cards/o/OgrePainbringer.java b/Mage.Sets/src/mage/cards/o/OgrePainbringer.java new file mode 100644 index 0000000000..6a51e5b650 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OgrePainbringer.java @@ -0,0 +1,38 @@ +package mage.cards.o; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class OgrePainbringer extends CardImpl { + + public OgrePainbringer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + this.subtype.add(SubType.OGRE); + + this.power = new MageInt(7); + this.toughness = new MageInt(3); + + // When Ogre Painbringer enters the battlefield, it deals 3 damage to each player. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DamagePlayersEffect(3, TargetController.ANY, "it"))); + } + + public OgrePainbringer(final OgrePainbringer card) { + super(card); + } + + @Override + public OgrePainbringer copy() { + return new OgrePainbringer(this); + } +} From bebc0cbfccfc66712cc9bc39af012212377b7d70 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:37:25 +0400 Subject: [PATCH 035/167] [ANA] - implemented River's Favor --- Mage.Sets/src/mage/cards/r/RiversFavor.java | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RiversFavor.java diff --git a/Mage.Sets/src/mage/cards/r/RiversFavor.java b/Mage.Sets/src/mage/cards/r/RiversFavor.java new file mode 100644 index 0000000000..523500e1ed --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RiversFavor.java @@ -0,0 +1,47 @@ +package mage.cards.r; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class RiversFavor extends CardImpl { + + public RiversFavor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +1/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1))); + } + + public RiversFavor(final RiversFavor card) { + super(card); + } + + @Override + public RiversFavor copy() { + return new RiversFavor(this); + } +} \ No newline at end of file From 0fef87dd28fc85876655cf030a333553ce594c1f Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:40:15 +0400 Subject: [PATCH 036/167] [ANA] - implemented Shorecomber Crab --- .../src/mage/cards/s/ShorecomberCrab.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShorecomberCrab.java diff --git a/Mage.Sets/src/mage/cards/s/ShorecomberCrab.java b/Mage.Sets/src/mage/cards/s/ShorecomberCrab.java new file mode 100644 index 0000000000..03dee68e49 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShorecomberCrab.java @@ -0,0 +1,32 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class ShorecomberCrab extends CardImpl { + + public ShorecomberCrab(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + this.subtype.add(SubType.CRAB); + + this.power = new MageInt(0); + this.toughness = new MageInt(4); + } + + public ShorecomberCrab(final ShorecomberCrab card) { + super(card); + } + + @Override + public ShorecomberCrab copy() { + return new ShorecomberCrab(this); + } +} From 2aa16bdf7d09089f87c05dd53cfffb3c040e306b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:41:45 +0400 Subject: [PATCH 037/167] [ANA] - implemented Shrine Keeper --- Mage.Sets/src/mage/cards/s/ShrineKeeper.java | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShrineKeeper.java diff --git a/Mage.Sets/src/mage/cards/s/ShrineKeeper.java b/Mage.Sets/src/mage/cards/s/ShrineKeeper.java new file mode 100644 index 0000000000..67682826d7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShrineKeeper.java @@ -0,0 +1,32 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class ShrineKeeper extends CardImpl { + + public ShrineKeeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.subtype.add(SubType.HUMAN, SubType.CLERIC); + + this.power = new MageInt(2); + this.toughness = new MageInt(2); + } + + public ShrineKeeper(final ShrineKeeper card) { + super(card); + } + + @Override + public ShrineKeeper copy() { + return new ShrineKeeper(this); + } +} From 9207275936e10846af5a3249f5b8f26eda911cec Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:46:45 +0400 Subject: [PATCH 038/167] [ANA] - implemented Soulhunter Rakshasa --- .../src/mage/cards/s/SoulhunterRakshasa.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java diff --git a/Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java b/Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java new file mode 100644 index 0000000000..e3725ae068 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java @@ -0,0 +1,45 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.CantBlockAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetOpponentOrPlaneswalker; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class SoulhunterRakshasa extends CardImpl { + + public SoulhunterRakshasa(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.subtype.add(SubType.CAT, SubType.DEMON); + + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Soulhunter Rakshasa can’t block. + this.addAbility(new CantBlockAbility()); + + // When Soulhunter Rakshasa enters the battlefield, it deals 5 damage to target opponent. + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2, "it"), false); + ability.addTarget(new TargetOpponentOrPlaneswalker()); + this.addAbility(ability); + } + + public SoulhunterRakshasa(final SoulhunterRakshasa card) { + super(card); + } + + @Override + public SoulhunterRakshasa copy() { + return new SoulhunterRakshasa(this); + } +} From 56d8887cf847b94060f259d1b488b4985679367e Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 18:57:58 +0400 Subject: [PATCH 039/167] [ANA] - implemented Tactical Advantage --- .../src/mage/cards/t/TacticalAdvantage.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TacticalAdvantage.java diff --git a/Mage.Sets/src/mage/cards/t/TacticalAdvantage.java b/Mage.Sets/src/mage/cards/t/TacticalAdvantage.java new file mode 100644 index 0000000000..52774236e1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TacticalAdvantage.java @@ -0,0 +1,51 @@ +package mage.cards.t; + +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.BlockedPredicate; +import mage.filter.predicate.permanent.BlockingPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class TacticalAdvantage extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blocking or blocked creature you control"); + + static { + filter.add( + Predicates.or( + new BlockingPredicate(), + new BlockedPredicate() + + )); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public TacticalAdvantage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Target blocking or blocked creature you control gets +2/+2 until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + } + + public TacticalAdvantage(final TacticalAdvantage card) { + super(card); + } + + @Override + public TacticalAdvantage copy() { + return new TacticalAdvantage(this); + } +} From e04705d914cf206926b19bd14f348896a05824e8 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 19:00:14 +0400 Subject: [PATCH 040/167] [ANA] - implemented Titanic Pelagosaur --- .../src/mage/cards/t/TitanicPelagosaur.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TitanicPelagosaur.java diff --git a/Mage.Sets/src/mage/cards/t/TitanicPelagosaur.java b/Mage.Sets/src/mage/cards/t/TitanicPelagosaur.java new file mode 100644 index 0000000000..221dfc8945 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TitanicPelagosaur.java @@ -0,0 +1,32 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class TitanicPelagosaur extends CardImpl { + + public TitanicPelagosaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); + this.subtype.add(SubType.DINOSAUR); + + this.power = new MageInt(4); + this.toughness = new MageInt(6); + } + + public TitanicPelagosaur(final TitanicPelagosaur card) { + super(card); + } + + @Override + public TitanicPelagosaur copy() { + return new TitanicPelagosaur(this); + } +} From cf82c15aad95e32b6793fc22a91ed62d9f328022 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 19:01:43 +0400 Subject: [PATCH 041/167] [ANA] - implemented Treetop Warden --- Mage.Sets/src/mage/cards/t/TreetopWarden.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TreetopWarden.java diff --git a/Mage.Sets/src/mage/cards/t/TreetopWarden.java b/Mage.Sets/src/mage/cards/t/TreetopWarden.java new file mode 100644 index 0000000000..2b4b7d2b30 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TreetopWarden.java @@ -0,0 +1,32 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class TreetopWarden extends CardImpl { + + public TreetopWarden(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.subtype.add(SubType.ELF, SubType.WARRIOR); + + this.power = new MageInt(2); + this.toughness = new MageInt(2); + } + + public TreetopWarden(final TreetopWarden card) { + super(card); + } + + @Override + public TreetopWarden copy() { + return new TreetopWarden(this); + } +} From 925fb1c5339357ab3a1373f93a03871262e2454e Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 19:03:29 +0400 Subject: [PATCH 042/167] [ANA] - implemented Zephyr Gull --- Mage.Sets/src/mage/cards/z/ZephyrGull.java | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZephyrGull.java diff --git a/Mage.Sets/src/mage/cards/z/ZephyrGull.java b/Mage.Sets/src/mage/cards/z/ZephyrGull.java new file mode 100644 index 0000000000..5b24699205 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZephyrGull.java @@ -0,0 +1,36 @@ +package mage.cards.z; + +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class ZephyrGull extends CardImpl { + + public ZephyrGull(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + this.subtype.add(SubType.BIRD); + + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + } + + public ZephyrGull(final ZephyrGull card) { + super(card); + } + + @Override + public ZephyrGull copy() { + return new ZephyrGull(this); + } +} From afe947f4573acf18f78da4618da862fb4eac6fa7 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 19:36:18 +0400 Subject: [PATCH 043/167] [ANA] - implemented Confront the Assault --- .../src/mage/cards/c/ConfrontTheAssault.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java diff --git a/Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java b/Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java new file mode 100644 index 0000000000..9193d2c747 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java @@ -0,0 +1,73 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.SpiritWhiteToken; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class ConfrontTheAssault extends CardImpl { + + public ConfrontTheAssault(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{W}"); + + // Cast this spell only if a creature is attacking you. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new ConfrontTheAssaultRestrictEffect())); + + // Create three 1/1 white Spirit creature tokens with flying. + this.getSpellAbility().addEffect(new CreateTokenEffect(new SpiritWhiteToken("ANA"), 3)); + } + + public ConfrontTheAssault(final ConfrontTheAssault card) { + super(card); + } + + @Override + public ConfrontTheAssault copy() { + return new ConfrontTheAssault(this); + } +} + +class ConfrontTheAssaultRestrictEffect extends ContinuousRuleModifyingEffectImpl { + + ConfrontTheAssaultRestrictEffect() { + super(Duration.EndOfGame, Outcome.Detriment); + staticText = "Cast this spell only if a creature is attacking you."; + } + + ConfrontTheAssaultRestrictEffect(final ConfrontTheAssaultRestrictEffect effect) { + super(effect); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED + && event.getTargetId().equals(source.getControllerId())) { + return true; + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public ConfrontTheAssaultRestrictEffect copy() { + return new ConfrontTheAssaultRestrictEffect(this); + } +} \ No newline at end of file From 10f56fb2a16ff0e6c36ba86529c0a5b70493da82 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 19:37:56 +0400 Subject: [PATCH 044/167] [ANA] - added White Spirit token --- Mage.Client/src/main/resources/card-pictures-tok.txt | 1 + .../main/java/mage/game/permanent/token/SpiritWhiteToken.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Client/src/main/resources/card-pictures-tok.txt b/Mage.Client/src/main/resources/card-pictures-tok.txt index 61e9eef56c..d6fb91a0d8 100644 --- a/Mage.Client/src/main/resources/card-pictures-tok.txt +++ b/Mage.Client/src/main/resources/card-pictures-tok.txt @@ -106,6 +106,7 @@ |Generate|PLANE:PCA|Plane - Turri Island|||TurriIslandPlane| |Generate|PLANE:PCA|Plane - Undercity Reaches|||UndercityReachesPlane| |Generate|TOK:ANA|Goblin|||GoblinToken| +|Generate|TOK:ANA|Spirit|||SpiritWhiteToken| |Generate|TOK:PCA|Eldrazi|||EldraziAnnihilatorToken| |Generate|TOK:10E|Ape|||PongifyApeToken| |Generate|TOK:10E|Dragon|||DragonToken2| diff --git a/Mage/src/main/java/mage/game/permanent/token/SpiritWhiteToken.java b/Mage/src/main/java/mage/game/permanent/token/SpiritWhiteToken.java index 5b856ddeda..64668eb42a 100644 --- a/Mage/src/main/java/mage/game/permanent/token/SpiritWhiteToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/SpiritWhiteToken.java @@ -17,7 +17,7 @@ public final class SpiritWhiteToken extends TokenImpl { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("AVR", "C14", "CNS", "DDC", "DDK", "FRF", "ISD", "KTK", "M15", "MM2", "SHM", "SOI", "EMA", "C16", "MM3", "CMA", "E01")); + tokenImageSets.addAll(Arrays.asList("AVR", "C14", "CNS", "DDC", "DDK", "FRF", "ISD", "KTK", "M15", "MM2", "SHM", "SOI", "EMA", "C16", "MM3", "CMA", "E01", "ANA")); } public SpiritWhiteToken() { From 74fb0acc7512398f81f1e223897e3b3ee4cf84fe Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 20:36:59 +0400 Subject: [PATCH 045/167] [ANA] - fixed Confront the Assault --- .../src/mage/cards/c/ConfrontTheAssault.java | 50 ++++--------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java b/Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java index 9193d2c747..985bc5f919 100644 --- a/Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java +++ b/Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java @@ -1,18 +1,16 @@ package mage.cards.c; import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AttackedThisStepCondition; import mage.abilities.effects.common.CreateTokenEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; +import mage.constants.PhaseStep; +import mage.constants.TurnPhase; import mage.game.permanent.token.SpiritWhiteToken; +import mage.watchers.common.PlayerAttackedStepWatcher; import java.util.UUID; @@ -25,7 +23,12 @@ public final class ConfrontTheAssault extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{W}"); // Cast this spell only if a creature is attacking you. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new ConfrontTheAssaultRestrictEffect())); + Ability ability = new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance, + "Cast this spell only if a creature is attacking you." + ); + ability.addWatcher(new PlayerAttackedStepWatcher()); + this.addAbility(ability); // Create three 1/1 white Spirit creature tokens with flying. this.getSpellAbility().addEffect(new CreateTokenEffect(new SpiritWhiteToken("ANA"), 3)); @@ -39,35 +42,4 @@ public final class ConfrontTheAssault extends CardImpl { public ConfrontTheAssault copy() { return new ConfrontTheAssault(this); } -} - -class ConfrontTheAssaultRestrictEffect extends ContinuousRuleModifyingEffectImpl { - - ConfrontTheAssaultRestrictEffect() { - super(Duration.EndOfGame, Outcome.Detriment); - staticText = "Cast this spell only if a creature is attacking you."; - } - - ConfrontTheAssaultRestrictEffect(final ConfrontTheAssaultRestrictEffect effect) { - super(effect); - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED - && event.getTargetId().equals(source.getControllerId())) { - return true; - } - return false; - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public ConfrontTheAssaultRestrictEffect copy() { - return new ConfrontTheAssaultRestrictEffect(this); - } } \ No newline at end of file From 43655845e7386baa76aff3531bdc0ab1c9772331 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 20:53:23 +0400 Subject: [PATCH 046/167] Tests: fixed deck cards amount tests --- .../test/serverside/deck/DeckValidatorTest.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/deck/DeckValidatorTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/deck/DeckValidatorTest.java index e472754c2a..3feddbd4eb 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/deck/DeckValidatorTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/deck/DeckValidatorTest.java @@ -59,13 +59,9 @@ public class DeckValidatorTest extends MageTestBase { } @Test - public void testStandardValid() { + public void testStandardDeckCardsAmountValid() { ArrayList deck = new ArrayList<>(); - - deck.add(new CardNameAmount("MPS-AKH", 28, 4)); // Rhonas the Indomitable - deck.add(new CardNameAmount("Built to Smash", 4)); - deck.add(new CardNameAmount("Heroic Intervention", 4)); - deck.add(new CardNameAmount("Mountain", 48)); + deck.add(new CardNameAmount("Mountain", 60)); DeckValidator validator = new Standard(); boolean validationSuccessful = testDeckValid(validator, deck); @@ -73,13 +69,9 @@ public class DeckValidatorTest extends MageTestBase { } @Test - public void testStandardNotValid() { + public void testStandardDeckCardsAmountNotValid() { ArrayList deck = new ArrayList<>(); - - deck.add(new CardNameAmount("MPS-AKH", 28, 4)); // Rhonas the Indomitable - deck.add(new CardNameAmount("Built to Smash", 4)); - deck.add(new CardNameAmount("Heroic Intervention", 4)); - deck.add(new CardNameAmount("Mountain", 47)); + deck.add(new CardNameAmount("Mountain", 59)); ArrayList sideboard = new ArrayList<>(); sideboard.add(new CardNameAmount("Mountain", 16)); From 1c95ed3b08bd3060dd9726c823b911da188b1ffd Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 20:54:46 +0400 Subject: [PATCH 047/167] * Added new set Arena New Player Experience (ANA) with 39 cards (18 new); --- .../card/dl/sources/ScryfallImageSource.java | 1 + .../src/mage/cards/g/GoblinGangLeader.java | 2 +- .../mage/sets/ArenaNewPlayerExperience.java | 63 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/sets/ArenaNewPlayerExperience.java diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 7f2bc5825f..4cac40e221 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -236,6 +236,7 @@ public enum ScryfallImageSource implements CardImageSource { supportedSets.add("GPX"); supportedSets.add("ATH"); supportedSets.add("GRC"); + supportedSets.add("ANA"); } @Override diff --git a/Mage.Sets/src/mage/cards/g/GoblinGangLeader.java b/Mage.Sets/src/mage/cards/g/GoblinGangLeader.java index c39be8d432..db0e80fc8b 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinGangLeader.java +++ b/Mage.Sets/src/mage/cards/g/GoblinGangLeader.java @@ -25,7 +25,7 @@ public final class GoblinGangLeader extends CardImpl { this.toughness = new MageInt(2); // When Goblin Gang Leader enters the battlefield, create two 1/1 red Goblin creature tokens. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoblinToken(), 2))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoblinToken("ANA"), 2))); } public GoblinGangLeader(final GoblinGangLeader card) { diff --git a/Mage.Sets/src/mage/sets/ArenaNewPlayerExperience.java b/Mage.Sets/src/mage/sets/ArenaNewPlayerExperience.java new file mode 100644 index 0000000000..aaad1327f9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ArenaNewPlayerExperience.java @@ -0,0 +1,63 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author JayDi85 + */ +public final class ArenaNewPlayerExperience extends ExpansionSet { + + private static final ArenaNewPlayerExperience instance = new ArenaNewPlayerExperience(); + + public static ArenaNewPlayerExperience getInstance() { + return instance; + } + + private ArenaNewPlayerExperience() { + super("Arena New Player Experience", "ANA", ExpansionSet.buildDate(2018, 7, 29), SetType.MAGIC_ONLINE); + this.hasBoosters = false; + this.hasBasicLands = false; + + cards.add(new SetCardInfo("Altar's Reap", 24, Rarity.COMMON, mage.cards.a.AltarsReap.class)); + cards.add(new SetCardInfo("Ambition's Cost", 25, Rarity.UNCOMMON, mage.cards.a.AmbitionsCost.class)); + cards.add(new SetCardInfo("Angelic Reward", 1, Rarity.UNCOMMON, mage.cards.a.AngelicReward.class)); + cards.add(new SetCardInfo("Blinding Radiance", 2, Rarity.UNCOMMON, mage.cards.b.BlindingRadiance.class)); + cards.add(new SetCardInfo("Chaos Maw", 36, Rarity.RARE, mage.cards.c.ChaosMaw.class)); + cards.add(new SetCardInfo("Confront the Assault", 3, Rarity.UNCOMMON, mage.cards.c.ConfrontTheAssault.class)); + cards.add(new SetCardInfo("Cruel Cut", 26, Rarity.COMMON, mage.cards.c.CruelCut.class)); + cards.add(new SetCardInfo("Divination", 14, Rarity.COMMON, mage.cards.d.Divination.class)); + cards.add(new SetCardInfo("Doublecast", 37, Rarity.UNCOMMON, mage.cards.d.Doublecast.class)); + cards.add(new SetCardInfo("Feral Roar", 46, Rarity.COMMON, mage.cards.f.FeralRoar.class)); + cards.add(new SetCardInfo("Goblin Bruiser", 39, Rarity.UNCOMMON, mage.cards.g.GoblinBruiser.class)); + cards.add(new SetCardInfo("Goblin Gang Leader", 40, Rarity.UNCOMMON, mage.cards.g.GoblinGangLeader.class)); + cards.add(new SetCardInfo("Goblin Grenade", 41, Rarity.UNCOMMON, mage.cards.g.GoblinGrenade.class)); + cards.add(new SetCardInfo("Inspiring Commander", 5, Rarity.RARE, mage.cards.i.InspiringCommander.class)); + cards.add(new SetCardInfo("Knight's Pledge", 6, Rarity.COMMON, mage.cards.k.KnightsPledge.class)); + cards.add(new SetCardInfo("Loxodon Line Breaker", 7, Rarity.COMMON, mage.cards.l.LoxodonLineBreaker.class)); + cards.add(new SetCardInfo("Miasmic Mummy", 29, Rarity.COMMON, mage.cards.m.MiasmicMummy.class)); + cards.add(new SetCardInfo("Nimble Pilferer", 31, Rarity.COMMON, mage.cards.n.NimblePilferer.class)); + cards.add(new SetCardInfo("Ogre Painbringer", 42, Rarity.RARE, mage.cards.o.OgrePainbringer.class)); + cards.add(new SetCardInfo("Overflowing Insight", 16, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); + cards.add(new SetCardInfo("Raging Goblin", 43, Rarity.COMMON, mage.cards.r.RagingGoblin.class)); + cards.add(new SetCardInfo("Renegade Demon", 33, Rarity.COMMON, mage.cards.r.RenegadeDemon.class)); + cards.add(new SetCardInfo("Rise from the Grave", 34, Rarity.UNCOMMON, mage.cards.r.RiseFromTheGrave.class)); + cards.add(new SetCardInfo("River's Favor", 17, Rarity.COMMON, mage.cards.r.RiversFavor.class)); + cards.add(new SetCardInfo("Rumbling Baloth", 47, Rarity.COMMON, mage.cards.r.RumblingBaloth.class)); + cards.add(new SetCardInfo("Sanctuary Cat", 8, Rarity.COMMON, mage.cards.s.SanctuaryCat.class)); + cards.add(new SetCardInfo("Seismic Rupture", 44, Rarity.UNCOMMON, mage.cards.s.SeismicRupture.class)); + cards.add(new SetCardInfo("Serra Angel", 9, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class)); + cards.add(new SetCardInfo("Shorecomber Crab", 18, Rarity.COMMON, mage.cards.s.ShorecomberCrab.class)); + cards.add(new SetCardInfo("Shrine Keeper", 10, Rarity.COMMON, mage.cards.s.ShrineKeeper.class)); + cards.add(new SetCardInfo("Soulhunter Rakshasa", 35, Rarity.RARE, mage.cards.s.SoulhunterRakshasa.class)); + cards.add(new SetCardInfo("Spiritual Guardian", 11, Rarity.COMMON, mage.cards.s.SpiritualGuardian.class)); + cards.add(new SetCardInfo("Tactical Advantage", 12, Rarity.COMMON, mage.cards.t.TacticalAdvantage.class)); + cards.add(new SetCardInfo("Take Vengeance", 13, Rarity.COMMON, mage.cards.t.TakeVengeance.class)); + cards.add(new SetCardInfo("Titanic Pelagosaur", 19, Rarity.UNCOMMON, mage.cards.t.TitanicPelagosaur.class)); + cards.add(new SetCardInfo("Treetop Warden", 48, Rarity.COMMON, mage.cards.t.TreetopWarden.class)); + cards.add(new SetCardInfo("Volcanic Dragon", 45, Rarity.UNCOMMON, mage.cards.v.VolcanicDragon.class)); + cards.add(new SetCardInfo("Waterknot", 22, Rarity.COMMON, mage.cards.w.Waterknot.class)); + cards.add(new SetCardInfo("Zephyr Gull", 23, Rarity.COMMON, mage.cards.z.ZephyrGull.class)); + } +} \ No newline at end of file From d661b0e1e90a1cbe9ec7be9763e2acaa70b2be1f Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 9 Oct 2018 21:09:01 +0400 Subject: [PATCH 048/167] [ANA] - fixed ability text --- Mage.Sets/src/mage/cards/i/InspiringCommander.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/InspiringCommander.java b/Mage.Sets/src/mage/cards/i/InspiringCommander.java index a4760c20d1..ad50beeafc 100644 --- a/Mage.Sets/src/mage/cards/i/InspiringCommander.java +++ b/Mage.Sets/src/mage/cards/i/InspiringCommander.java @@ -44,7 +44,7 @@ public final class InspiringCommander extends CardImpl { Effect effect2 = new DrawCardSourceControllerEffect(1); Ability ability = new EntersBattlefieldControlledTriggeredAbility( Zone.BATTLEFIELD, effect1, filter, false); - ability.addEffect(effect2); + ability.addEffect(effect2.setText("and draw a card")); this.addAbility(ability); } From 8b0393cb96acbfce0b947f20dfc245af10c3138e Mon Sep 17 00:00:00 2001 From: L_J Date: Tue, 9 Oct 2018 18:23:40 +0000 Subject: [PATCH 049/167] Fix Soulhunter Rakshasa damage value --- Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java b/Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java index e3725ae068..dba46f380c 100644 --- a/Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java +++ b/Mage.Sets/src/mage/cards/s/SoulhunterRakshasa.java @@ -29,7 +29,7 @@ public final class SoulhunterRakshasa extends CardImpl { this.addAbility(new CantBlockAbility()); // When Soulhunter Rakshasa enters the battlefield, it deals 5 damage to target opponent. - Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2, "it"), false); + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(5, "it"), false); ability.addTarget(new TargetOpponentOrPlaneswalker()); this.addAbility(ability); } From 26913923faf3cf4eb129c3fcee40394948bfe6dc Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 10 Oct 2018 01:21:43 +0400 Subject: [PATCH 050/167] Refactor: replaced duplicated ability - CreatureEntersBattlefieldTriggeredAbility by EntersBattlefieldControlledTriggeredAbility; --- .gitignore | 1 + Mage.Sets/src/mage/cards/a/AngelsTomb.java | 25 ++-- .../src/mage/cards/c/CatharsCrusade.java | 17 ++- .../src/mage/cards/d/DecoctionModule.java | 16 ++- .../mage/cards/f/ForerunnerOfTheEmpire.java | 16 ++- .../src/mage/cards/l/LeylineOfVitality.java | 19 ++- .../src/mage/cards/s/SosukesSummons.java | 19 ++- Mage.Sets/src/mage/cards/v/ValorInAkros.java | 17 ++- .../src/mage/cards/v/VigilanteJustice.java | 19 ++- ...tureEntersBattlefieldTriggeredAbility.java | 123 ------------------ .../main/java/mage/filter/StaticFilters.java | 39 +++++- 11 files changed, 134 insertions(+), 177 deletions(-) delete mode 100644 Mage/src/main/java/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java diff --git a/.gitignore b/.gitignore index 39a0d76c16..d60de4860c 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,7 @@ Mage.Verify/AllCards.json.zip Mage.Verify/AllSets.json.zip Mage.Verify/AllCards.json Mage.Verify/AllSets.json +/db releases Utils/author.txt diff --git a/Mage.Sets/src/mage/cards/a/AngelsTomb.java b/Mage.Sets/src/mage/cards/a/AngelsTomb.java index 6cd8c0e5ad..0f3b20d28c 100644 --- a/Mage.Sets/src/mage/cards/a/AngelsTomb.java +++ b/Mage.Sets/src/mage/cards/a/AngelsTomb.java @@ -1,10 +1,8 @@ package mage.cards.a; -import java.util.UUID; - -import mage.MageInt; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -12,10 +10,12 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.game.permanent.token.TokenImpl; -import mage.game.permanent.token.Token; +import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.permanent.token.custom.CreatureToken; +import java.util.UUID; + /** * @author Loki */ @@ -25,12 +25,13 @@ public final class AngelsTomb extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // Whenever a creature enters the battlefield under your control, you may have Angel's Tomb become a 3/3 white Angel artifact creature with flying until end of turn. - this.addAbility(new CreatureEntersBattlefieldTriggeredAbility(new BecomesCreatureSourceEffect( - new CreatureToken(3, 3, "3/3 white Angel artifact creature with flying") - .withColor("W") - .withSubType(SubType.ANGEL) - .withAbility(FlyingAbility.getInstance()), - "", Duration.EndOfTurn), true)); + Effect effect = new BecomesCreatureSourceEffect(new CreatureToken(3, 3, "3/3 white Angel artifact creature with flying") + .withColor("W") + .withSubType(SubType.ANGEL) + .withAbility(FlyingAbility.getInstance()), + "", Duration.EndOfTurn) + .setText("have {this} become a 3/3 white Angel artifact creature with flying until end of turn"); + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, StaticFilters.FILTER_PERMANENT_CREATURE, true)); } public AngelsTomb(final AngelsTomb card) { diff --git a/Mage.Sets/src/mage/cards/c/CatharsCrusade.java b/Mage.Sets/src/mage/cards/c/CatharsCrusade.java index bfb4f678fb..59a6ce427e 100644 --- a/Mage.Sets/src/mage/cards/c/CatharsCrusade.java +++ b/Mage.Sets/src/mage/cards/c/CatharsCrusade.java @@ -1,27 +1,34 @@ package mage.cards.c; -import java.util.UUID; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.effects.common.counter.AddCountersAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Zone; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; +import java.util.UUID; + /** - * * @author Loki */ public final class CatharsCrusade extends CardImpl { public CatharsCrusade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}"); // Whenever a creature enters the battlefield under your control, put a +1/+1 counter on each creature you control. - this.addAbility(new CreatureEntersBattlefieldTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()))); + this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, + new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()), + StaticFilters.FILTER_PERMANENT_CREATURE_A, + false) + ); } public CatharsCrusade(final CatharsCrusade card) { diff --git a/Mage.Sets/src/mage/cards/d/DecoctionModule.java b/Mage.Sets/src/mage/cards/d/DecoctionModule.java index 95b4a39c12..c870592f42 100644 --- a/Mage.Sets/src/mage/cards/d/DecoctionModule.java +++ b/Mage.Sets/src/mage/cards/d/DecoctionModule.java @@ -1,9 +1,8 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; @@ -13,19 +12,26 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** - * * @author emerald000 */ public final class DecoctionModule extends CardImpl { public DecoctionModule(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // Whenever a creature enters the battlefield under your control, you get {E}. - this.addAbility(new CreatureEntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(1))); + this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, + new GetEnergyCountersControllerEffect(1), + StaticFilters.FILTER_PERMANENT_CREATURE_A, + false) + ); // {4}, {T}: Return target creature you control to its owner's hand. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new GenericManaCost(4)); diff --git a/Mage.Sets/src/mage/cards/f/ForerunnerOfTheEmpire.java b/Mage.Sets/src/mage/cards/f/ForerunnerOfTheEmpire.java index a2789bf555..a33e5bfc1b 100644 --- a/Mage.Sets/src/mage/cards/f/ForerunnerOfTheEmpire.java +++ b/Mage.Sets/src/mage/cards/f/ForerunnerOfTheEmpire.java @@ -1,23 +1,26 @@ package mage.cards.f; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DamageAllEffect; import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; import mage.filter.common.FilterBySubtypeCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCardInLibrary; +import java.util.UUID; + /** - * * @author JayDi85 */ public final class ForerunnerOfTheEmpire extends CardImpl { @@ -49,12 +52,11 @@ public final class ForerunnerOfTheEmpire extends CardImpl { ); // Whenever a Dinosaur enters the battlefield under your control, you may have Forerunner of the Empire deal 1 damage to each creature. - Ability ability = new CreatureEntersBattlefieldTriggeredAbility( + Ability ability = new EntersBattlefieldControlledTriggeredAbility( Zone.BATTLEFIELD, new DamageAllEffect(1, new FilterCreaturePermanent()).setText("have {this} deal 1 damage to each creature"), filterAnyDinosaur, - true, - false); + true); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/l/LeylineOfVitality.java b/Mage.Sets/src/mage/cards/l/LeylineOfVitality.java index 42be613481..8808969cec 100644 --- a/Mage.Sets/src/mage/cards/l/LeylineOfVitality.java +++ b/Mage.Sets/src/mage/cards/l/LeylineOfVitality.java @@ -1,8 +1,7 @@ package mage.cards.l; -import java.util.UUID; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; @@ -14,8 +13,9 @@ import mage.constants.Duration; import mage.constants.Zone; import mage.filter.StaticFilters; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public final class LeylineOfVitality extends CardImpl { @@ -23,10 +23,19 @@ public final class LeylineOfVitality extends CardImpl { public LeylineOfVitality(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}"); + // If Leyline of Vitality is in your opening hand, you may begin the game with it on the battlefield. this.addAbility(LeylineAbility.getInstance()); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(0, 1, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE, false))); - this.addAbility(new CreatureEntersBattlefieldTriggeredAbility(new GainLifeEffect(1), true)); + // Creatures you control get +0/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(0, 1, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES, false))); + + // Whenever a creature enters the battlefield under your control, you may gain 1 life. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, + new GainLifeEffect(1), + StaticFilters.FILTER_PERMANENT_CREATURE_A, + true) + ); } public LeylineOfVitality(final LeylineOfVitality card) { diff --git a/Mage.Sets/src/mage/cards/s/SosukesSummons.java b/Mage.Sets/src/mage/cards/s/SosukesSummons.java index e5ea61eb3b..f24676ab3a 100644 --- a/Mage.Sets/src/mage/cards/s/SosukesSummons.java +++ b/Mage.Sets/src/mage/cards/s/SosukesSummons.java @@ -1,8 +1,7 @@ package mage.cards.s; -import java.util.UUID; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; import mage.cards.CardImpl; @@ -16,8 +15,9 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.permanent.token.SnakeToken; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class SosukesSummons extends CardImpl { @@ -25,19 +25,24 @@ public final class SosukesSummons extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken Snake"); static { - filter.add(new SubtypePredicate(SubType.SNAKE)); - filter.add(Predicates.not(new TokenPredicate())); + filter.add(new SubtypePredicate(SubType.SNAKE)); + filter.add(Predicates.not(new TokenPredicate())); } public SosukesSummons(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); // Create two 1/1 green Snake creature tokens. this.getSpellAbility().addEffect(new CreateTokenEffect(new SnakeToken(), 2)); // Whenever a nontoken Snake enters the battlefield under your control, you may return Sosuke's Summons from your graveyard to your hand. - this.addAbility(new CreatureEntersBattlefieldTriggeredAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), filter, true, false)); + this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + Zone.GRAVEYARD, + new ReturnSourceFromGraveyardToHandEffect(), + filter, + true) + ); } diff --git a/Mage.Sets/src/mage/cards/v/ValorInAkros.java b/Mage.Sets/src/mage/cards/v/ValorInAkros.java index 851ff2e66a..3f778cba22 100644 --- a/Mage.Sets/src/mage/cards/v/ValorInAkros.java +++ b/Mage.Sets/src/mage/cards/v/ValorInAkros.java @@ -1,25 +1,32 @@ package mage.cards.v; -import java.util.UUID; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.StaticFilters; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class ValorInAkros extends CardImpl { public ValorInAkros(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); // Whenever a creature enters the battlefield under your control, creatures you control get +1/+1 until end of turn. - this.addAbility(new CreatureEntersBattlefieldTriggeredAbility(new BoostControlledEffect(1,1,Duration.EndOfTurn))); + this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, + new BoostControlledEffect(1, 1, Duration.EndOfTurn), + StaticFilters.FILTER_PERMANENT_CREATURE_A, + false) + ); } public ValorInAkros(final ValorInAkros card) { diff --git a/Mage.Sets/src/mage/cards/v/VigilanteJustice.java b/Mage.Sets/src/mage/cards/v/VigilanteJustice.java index e99e223b5f..791642147b 100644 --- a/Mage.Sets/src/mage/cards/v/VigilanteJustice.java +++ b/Mage.Sets/src/mage/cards/v/VigilanteJustice.java @@ -1,9 +1,8 @@ package mage.cards.v; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -14,24 +13,30 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.target.common.TargetAnyTarget; +import java.util.UUID; + /** - * * @author Loki */ public final class VigilanteJustice extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Human"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a Human"); static { - filter.add(new SubtypePredicate(SubType.HUMAN)); + filter.add(new SubtypePredicate(SubType.HUMAN)); } public VigilanteJustice(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); // Whenever a Human enters the battlefield under your control, Vigilante Justice deals 1 damage to any target. - Ability ability = new CreatureEntersBattlefieldTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), filter, false, false); + Ability ability = new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, + new DamageTargetEffect(1), + filter, + false + ); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage/src/main/java/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java deleted file mode 100644 index ba3e9555d7..0000000000 --- a/Mage/src/main/java/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java +++ /dev/null @@ -1,123 +0,0 @@ - -package mage.abilities.common; - -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; -import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; -import mage.game.Game; -import mage.game.events.EntersTheBattlefieldEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.target.Target; -import mage.target.TargetPlayer; -import mage.target.common.TargetCreaturePermanent; - -/** - * - * @author North - */ -public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityImpl { - - private boolean opponentController; - protected FilterCreaturePermanent filter = new FilterCreaturePermanent(); - - /** - * optional = false
- * opponentController = false - * - * @param effect - */ - public CreatureEntersBattlefieldTriggeredAbility(Effect effect) { - this(effect, false, false); - } - - /** - * opponentController = false - * - * @param effect - * @param optional - */ - public CreatureEntersBattlefieldTriggeredAbility(Effect effect, boolean optional) { - this(effect, optional, false); - } - - /** - * - * @param effect - * @param optional - * @param opponentController - */ - public CreatureEntersBattlefieldTriggeredAbility(Effect effect, boolean optional, boolean opponentController) { - this(Zone.BATTLEFIELD, effect, optional, opponentController); - - } - - /** - * @param zone - * @param effect - * @param optional - * @param opponentController - */ - public CreatureEntersBattlefieldTriggeredAbility(Zone zone, Effect effect, boolean optional, boolean opponentController) { - this(zone, effect, null, optional, opponentController); - } - - /** - * @param zone - * @param effect - * @param filter filter the triggering creatures - * @param optional - * @param opponentController - */ - public CreatureEntersBattlefieldTriggeredAbility(Zone zone, Effect effect, FilterCreaturePermanent filter, boolean optional, boolean opponentController) { - super(zone, effect, optional); - this.opponentController = opponentController; - if (filter != null) { - this.filter = filter; - } - } - - public CreatureEntersBattlefieldTriggeredAbility(CreatureEntersBattlefieldTriggeredAbility ability) { - super(ability); - this.opponentController = ability.opponentController; - this.filter = ability.filter; - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); - if (filter.match(permanent, sourceId, controllerId, game) - && (permanent.isControlledBy(this.controllerId) ^ opponentController)) { - if (!this.getTargets().isEmpty()) { - Target target = this.getTargets().get(0); - if (target instanceof TargetPlayer) { - target.add(permanent.getControllerId(), game); - } - if (target instanceof TargetCreaturePermanent) { - target.add(event.getTargetId(), game); - } - } - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever a " + filter.getMessage() + " enters the battlefield under " - + (opponentController ? "an opponent's control, " : "your control, ") - + super.getRule(); - } - - @Override - public CreatureEntersBattlefieldTriggeredAbility copy() { - return new CreatureEntersBattlefieldTriggeredAbility(this); - } -} diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 0fcf903c4c..4226afe876 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -23,7 +23,7 @@ import mage.filter.predicate.permanent.TokenPredicate; /** * A class that holds Filter objects that may not be modified without copying * before. This prevents the creation of thousands of filter objects. - * + *

* Because the filters are used application wide they may not be modified. * NEVER!!!!! But it's possible, so be careful! * @@ -42,6 +42,7 @@ public final class StaticFilters { static { FILTER_ENCHANTMENT_PERMANENT.setLockedFilter(true); } + public static final FilterCard FILTER_CARD = new FilterCard("card"); static { @@ -119,6 +120,7 @@ public final class StaticFilters { static { FILTER_CARD_NON_LAND.setLockedFilter(true); } + public static final FilterNonlandCard FILTER_CARD_A_NON_LAND = new FilterNonlandCard("a nonland card"); static { @@ -154,11 +156,13 @@ public final class StaticFilters { static { FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_ARTIFACT_CREATURE_PERMANENT = new FilterArtifactCreaturePermanent(); static { FILTER_ARTIFACT_CREATURE_PERMANENT.setLockedFilter(true); } + public static final FilterPermanent FILTER_PERMANENT_ARTIFACT_OR_CREATURE = new FilterPermanent("artifact or creature"); static { @@ -168,6 +172,7 @@ public final class StaticFilters { )); FILTER_PERMANENT_ARTIFACT_OR_CREATURE.setLockedFilter(true); } + public static final FilterPermanent FILTER_PERMANENT_ARTIFACT_CREATURE_OR_ENCHANTMENT = new FilterPermanent("artifact, creature, or enchantment"); static { @@ -178,6 +183,7 @@ public final class StaticFilters { )); FILTER_PERMANENT_ARTIFACT_CREATURE_OR_ENCHANTMENT.setLockedFilter(true); } + public static final FilterPermanent FILTER_PERMANENT_ARTIFACT_CREATURE_ENCHANTMENT_OR_LAND = new FilterPermanent("artifact, creature, enchantment, or land"); static { @@ -195,16 +201,19 @@ public final class StaticFilters { static { FILTER_CONTROLLED_PERMANENT.setLockedFilter(true); } + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT = new FilterControlledArtifactPermanent(); static { FILTER_CONTROLLED_PERMANENT_ARTIFACT.setLockedFilter(true); } + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN = new FilterControlledArtifactPermanent("an artifact"); static { FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN.setLockedFilter(true); } + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE = new FilterControlledPermanent("artifact or creature you control"); static { @@ -214,6 +223,7 @@ public final class StaticFilters { )); FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE.setLockedFilter(true); } + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_LAND = new FilterControlledLandPermanent(); static { @@ -232,12 +242,14 @@ public final class StaticFilters { FILTER_OPPONENTS_PERMANENT.add(new ControllerPredicate(TargetController.OPPONENT)); FILTER_OPPONENTS_PERMANENT.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_OPPONENTS_PERMANENT_CREATURE = new FilterCreaturePermanent("creature an opponent controls"); static { FILTER_OPPONENTS_PERMANENT_CREATURE.add(new ControllerPredicate(TargetController.OPPONENT)); FILTER_OPPONENTS_PERMANENT_CREATURE.setLockedFilter(true); } + public static final FilterPermanent FILTER_OPPONENTS_PERMANENT_ARTIFACT = new FilterPermanent("artifact an opponent controls"); static { @@ -245,6 +257,7 @@ public final class StaticFilters { FILTER_OPPONENTS_PERMANENT_ARTIFACT.add(new CardTypePredicate(CardType.ARTIFACT)); FILTER_OPPONENTS_PERMANENT_ARTIFACT.setLockedFilter(true); } + public static final FilterPermanent FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE = new FilterPermanent("artifact or creature an opponent controls"); static { @@ -280,12 +293,14 @@ public final class StaticFilters { static { FILTER_CONTROLLED_A_CREATURE.setLockedFilter(true); } + public static final FilterControlledCreaturePermanent FILTER_CONTROLLED_ANOTHER_CREATURE = new FilterControlledCreaturePermanent("another creature"); static { FILTER_CONTROLLED_ANOTHER_CREATURE.add(new AnotherPredicate()); FILTER_CONTROLLED_ANOTHER_CREATURE.setLockedFilter(true); } + public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_NON_LAND = new FilterControlledPermanent("nonland permanent"); static { @@ -294,6 +309,7 @@ public final class StaticFilters { ); FILTER_CONTROLLED_PERMANENT_NON_LAND.setLockedFilter(true); } + public static final FilterLandPermanent FILTER_LAND = new FilterLandPermanent(); static { @@ -331,6 +347,12 @@ public final class StaticFilters { FILTER_PERMANENT_CREATURE.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_A = new FilterCreaturePermanent("a creature"); + + static { + FILTER_PERMANENT_CREATURE_A.setLockedFilter(true); + } + public static final FilterPermanent FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A = new FilterPermanent("a creature or planeswalker"); static { @@ -344,33 +366,39 @@ public final class StaticFilters { static { FILTER_PERMANENT_A_CREATURE.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_CONTROLLED = new FilterCreaturePermanent("creature you control"); static { FILTER_PERMANENT_CREATURE_CONTROLLED.add(new ControllerPredicate(TargetController.YOU)); FILTER_PERMANENT_CREATURE_CONTROLLED.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURES = new FilterCreaturePermanent("creatures"); static { FILTER_PERMANENT_CREATURES.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURES_CONTROLLED = new FilterCreaturePermanent("creatures you control"); static { FILTER_PERMANENT_CREATURES_CONTROLLED.add(new ControllerPredicate(TargetController.YOU)); FILTER_PERMANENT_CREATURES_CONTROLLED.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_GOBLINS = new FilterCreaturePermanent(SubType.GOBLIN, "Goblin creatures"); static { FILTER_PERMANENT_CREATURE_GOBLINS.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_SLIVERS = new FilterCreaturePermanent(SubType.SLIVER, "all Sliver creatures"); static { FILTER_PERMANENT_CREATURE_SLIVERS.setLockedFilter(true); } + public static final FilterPlaneswalkerPermanent FILTER_PERMANENT_PLANESWALKER = new FilterPlaneswalkerPermanent(); static { @@ -388,12 +416,14 @@ public final class StaticFilters { static { FILTER_PERMANENTS_NON_LAND.setLockedFilter(true); } + public static final FilterStackObject FILTER_SPELL_OR_ABILITY_OPPONENTS = new FilterStackObject("spell or ability and opponent controls"); static { FILTER_SPELL_OR_ABILITY_OPPONENTS.add(new ControllerPredicate(TargetController.OPPONENT)); FILTER_SPELL_OR_ABILITY_OPPONENTS.setLockedFilter(true); } + public static final FilterStackObject FILTER_SPELL_OR_ABILITY = new FilterStackObject(); static { @@ -405,11 +435,13 @@ public final class StaticFilters { static { FILTER_SPELL_A_CREATURE.setLockedFilter(true); } + public static final FilterCreatureSpell FILTER_SPELL_CREATURE = new FilterCreatureSpell("creature spell"); static { FILTER_SPELL_CREATURE.setLockedFilter(true); } + public static final FilterSpell FILTER_SPELL_NON_CREATURE = (FilterSpell) new FilterSpell("noncreature spell").add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); static { @@ -444,6 +476,7 @@ public final class StaticFilters { )); FILTER_SPELL_AN_INSTANT_OR_SORCERY.setLockedFilter(true); } + public static final FilterSpell FILTER_SPELL_INSTANT_OR_SORCERY = new FilterSpell("instant or sorcery spell"); static { @@ -463,6 +496,7 @@ public final class StaticFilters { )); FILTER_SPELLS_INSTANT_OR_SORCERY.setLockedFilter(true); } + public static final FilterCreaturePermanent FILTER_CREATURE_TOKENS = new FilterCreaturePermanent("creature tokens"); static { @@ -484,6 +518,7 @@ public final class StaticFilters { FILTER_PERMANENT_AURA.add(new SubtypePredicate(SubType.AURA)); FILTER_PERMANENT_AURA.setLockedFilter(true); } + public static final FilterPermanent FILTER_PERMANENT_EQUIPMENT = new FilterPermanent(); static { @@ -491,6 +526,7 @@ public final class StaticFilters { FILTER_PERMANENT_EQUIPMENT.add(new SubtypePredicate(SubType.EQUIPMENT)); FILTER_PERMANENT_EQUIPMENT.setLockedFilter(true); } + public static final FilterPermanent FILTER_PERMANENT_FORTIFICATION = new FilterPermanent(); static { @@ -498,6 +534,7 @@ public final class StaticFilters { FILTER_PERMANENT_FORTIFICATION.add(new SubtypePredicate(SubType.FORTIFICATION)); FILTER_PERMANENT_FORTIFICATION.setLockedFilter(true); } + public static final FilterPermanent FILTER_PERMANENT_LEGENDARY = new FilterPermanent(); static { From 3fc1660f75d5144981ab578c261027c1a965189d Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 10 Oct 2018 01:27:58 +0400 Subject: [PATCH 051/167] Fixed abilities texts --- Mage.Sets/src/mage/cards/a/AngelsTomb.java | 7 ++++++- Mage.Sets/src/mage/cards/s/SosukesSummons.java | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AngelsTomb.java b/Mage.Sets/src/mage/cards/a/AngelsTomb.java index 0f3b20d28c..9eec7a6286 100644 --- a/Mage.Sets/src/mage/cards/a/AngelsTomb.java +++ b/Mage.Sets/src/mage/cards/a/AngelsTomb.java @@ -31,7 +31,12 @@ public final class AngelsTomb extends CardImpl { .withAbility(FlyingAbility.getInstance()), "", Duration.EndOfTurn) .setText("have {this} become a 3/3 white Angel artifact creature with flying until end of turn"); - this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, StaticFilters.FILTER_PERMANENT_CREATURE, true)); + this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, + effect, + StaticFilters.FILTER_PERMANENT_CREATURE_A, + true) + ); } public AngelsTomb(final AngelsTomb card) { diff --git a/Mage.Sets/src/mage/cards/s/SosukesSummons.java b/Mage.Sets/src/mage/cards/s/SosukesSummons.java index f24676ab3a..b3afeaf79f 100644 --- a/Mage.Sets/src/mage/cards/s/SosukesSummons.java +++ b/Mage.Sets/src/mage/cards/s/SosukesSummons.java @@ -22,7 +22,7 @@ import java.util.UUID; */ public final class SosukesSummons extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken Snake"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a nontoken Snake"); static { filter.add(new SubtypePredicate(SubType.SNAKE)); @@ -43,8 +43,6 @@ public final class SosukesSummons extends CardImpl { filter, true) ); - - } public SosukesSummons(final SosukesSummons card) { From 9500d8e154bbf679a61e0daf3463e9c8d8f85aea Mon Sep 17 00:00:00 2001 From: jmharmon <37360760+jmharmon@users.noreply.github.com> Date: Tue, 9 Oct 2018 20:12:09 -0700 Subject: [PATCH 052/167] Implement Soul Strings --- Mage.Sets/src/mage/sets/Prophecy.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 428e91c876..66b0ea67af 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -136,6 +136,7 @@ public final class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Silt Crawler", 123, Rarity.COMMON, mage.cards.s.SiltCrawler.class)); cards.add(new SetCardInfo("Snag", 124, Rarity.UNCOMMON, mage.cards.s.Snag.class)); cards.add(new SetCardInfo("Soul Charmer", 24, Rarity.COMMON, mage.cards.s.SoulCharmer.class)); + cards.add(new SetCardInfo("Soul Strings", 78, Rarity.COMMON, mage.cards.s.SoulStrings.class)); cards.add(new SetCardInfo("Spiketail Drake", 48, Rarity.UNCOMMON, mage.cards.s.SpiketailDrake.class)); cards.add(new SetCardInfo("Spiketail Hatchling", 49, Rarity.COMMON, mage.cards.s.SpiketailHatchling.class)); cards.add(new SetCardInfo("Spitting Spider", 125, Rarity.UNCOMMON, mage.cards.s.SpittingSpider.class)); From aac5135c44846544fc16111e3735bee3bbf3b917 Mon Sep 17 00:00:00 2001 From: jmharmon <37360760+jmharmon@users.noreply.github.com> Date: Tue, 9 Oct 2018 20:13:23 -0700 Subject: [PATCH 053/167] Implement Soul Strings --- Mage.Sets/src/mage/cards/s/SoulStrings.java | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoulStrings.java diff --git a/Mage.Sets/src/mage/cards/s/SoulStrings.java b/Mage.Sets/src/mage/cards/s/SoulStrings.java new file mode 100644 index 0000000000..b1a70905c3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoulStrings.java @@ -0,0 +1,41 @@ +package mage.cards.s; + +import mage.abilities.costs.mana.VariableManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterCreatureCard; +import mage.target.common.TargetCardInGraveyard; + +import java.util.UUID; + +/** + * + * @author jmharmon + */ + +public final class SoulStrings extends CardImpl { + + public SoulStrings(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}"); + + // Return two target creature cards from your graveyard to your hand unless any player pays {X}. + Effect effect = new DoUnlessAnyPlayerPaysEffect( + new ReturnFromGraveyardToHandTargetEffect(), new VariableManaCost() + ); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCardInGraveyard(2, new FilterCreatureCard("creature cards from your graveyard"))); + } + + public SoulStrings(final SoulStrings card) { + super(card); + } + + @Override + public SoulStrings copy() { + return new SoulStrings(this); + } +} From 9537a05552eea1b139fd1b43278c73fbfbbfbfd9 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 10 Oct 2018 08:47:53 +0400 Subject: [PATCH 054/167] Missing comments --- Mage.Sets/src/mage/cards/b/BeckonApparition.java | 4 +++- Mage.Sets/src/mage/cards/c/CoffinPurge.java | 9 ++++----- Mage.Sets/src/mage/cards/c/Cremate.java | 9 ++++++--- Mage.Sets/src/mage/cards/n/NoxiousRevival.java | 11 ++++++----- Mage.Sets/src/mage/cards/s/Shadowfeed.java | 8 ++++---- Mage.Sets/src/mage/cards/w/WildwoodRebirth.java | 8 ++++---- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BeckonApparition.java b/Mage.Sets/src/mage/cards/b/BeckonApparition.java index 9df22c5d0b..523332f22d 100644 --- a/Mage.Sets/src/mage/cards/b/BeckonApparition.java +++ b/Mage.Sets/src/mage/cards/b/BeckonApparition.java @@ -1,7 +1,6 @@ package mage.cards.b; -import java.util.UUID; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.cards.CardImpl; @@ -10,6 +9,8 @@ import mage.constants.CardType; import mage.game.permanent.token.BeckonApparitionToken; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** * @author Loki */ @@ -18,6 +19,7 @@ public final class BeckonApparition extends CardImpl { public BeckonApparition(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W/B}"); + // Exile target card from a graveyard. Create a 1/1 white and black Spirit creature token with flying. this.getSpellAbility().addEffect(new ExileTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInGraveyard()); this.getSpellAbility().addEffect(new CreateTokenEffect(new BeckonApparitionToken(), 1)); diff --git a/Mage.Sets/src/mage/cards/c/CoffinPurge.java b/Mage.Sets/src/mage/cards/c/CoffinPurge.java index 34d26d9c91..200d6a4a9c 100644 --- a/Mage.Sets/src/mage/cards/c/CoffinPurge.java +++ b/Mage.Sets/src/mage/cards/c/CoffinPurge.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.keyword.FlashbackAbility; @@ -11,21 +10,21 @@ import mage.constants.CardType; import mage.constants.TimingRule; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** - * * @author cbt33, jonubuu (Withered Wretch) */ public final class CoffinPurge extends CardImpl { public CoffinPurge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); // Exile target card from a graveyard. - this.getSpellAbility().addEffect(new ExileTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInGraveyard()); + // Flashback {B} this.addAbility(new FlashbackAbility(new ManaCostsImpl("{B}"), TimingRule.INSTANT)); } diff --git a/Mage.Sets/src/mage/cards/c/Cremate.java b/Mage.Sets/src/mage/cards/c/Cremate.java index a5e061094a..62c465e34f 100644 --- a/Mage.Sets/src/mage/cards/c/Cremate.java +++ b/Mage.Sets/src/mage/cards/c/Cremate.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.cards.CardImpl; @@ -9,17 +8,21 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** - * * @author Loki */ public final class Cremate extends CardImpl { public Cremate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); + // Exile target card from a graveyard. this.getSpellAbility().addEffect(new ExileTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInGraveyard()); + + // Draw a card. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); } diff --git a/Mage.Sets/src/mage/cards/n/NoxiousRevival.java b/Mage.Sets/src/mage/cards/n/NoxiousRevival.java index 64d5e54525..5a8ee8c05e 100644 --- a/Mage.Sets/src/mage/cards/n/NoxiousRevival.java +++ b/Mage.Sets/src/mage/cards/n/NoxiousRevival.java @@ -2,27 +2,28 @@ package mage.cards.n; -import java.util.UUID; import mage.abilities.effects.common.PutOnLibraryTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** - * * @author Loki */ public final class NoxiousRevival extends CardImpl { - public NoxiousRevival (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G/P}"); + public NoxiousRevival(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G/P}"); + // Put target card from a graveyard on top of its owner’s library. this.getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true)); this.getSpellAbility().addTarget(new TargetCardInGraveyard()); } - public NoxiousRevival (final NoxiousRevival card) { + public NoxiousRevival(final NoxiousRevival card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/s/Shadowfeed.java b/Mage.Sets/src/mage/cards/s/Shadowfeed.java index 8e615530b7..bd0c8400ff 100644 --- a/Mage.Sets/src/mage/cards/s/Shadowfeed.java +++ b/Mage.Sets/src/mage/cards/s/Shadowfeed.java @@ -1,7 +1,6 @@ package mage.cards.s; -import java.util.UUID; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; @@ -9,19 +8,20 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** - * * @author North */ public final class Shadowfeed extends CardImpl { public Shadowfeed(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); // Exile target card from a graveyard. this.getSpellAbility().addEffect(new ExileTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInGraveyard()); + // You gain 3 life. this.getSpellAbility().addEffect(new GainLifeEffect(3)); } diff --git a/Mage.Sets/src/mage/cards/w/WildwoodRebirth.java b/Mage.Sets/src/mage/cards/w/WildwoodRebirth.java index 3ce85f81a3..106fe3c6bc 100644 --- a/Mage.Sets/src/mage/cards/w/WildwoodRebirth.java +++ b/Mage.Sets/src/mage/cards/w/WildwoodRebirth.java @@ -1,16 +1,16 @@ package mage.cards.w; -import java.util.UUID; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.StaticFilters; -import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; /** - * * @author Plopman */ public final class WildwoodRebirth extends CardImpl { @@ -20,7 +20,7 @@ public final class WildwoodRebirth extends CardImpl { // Return target creature card from your graveyard to your hand. this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect()); - this.getSpellAbility().addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard()); } public WildwoodRebirth(final WildwoodRebirth card) { From 66b5f3a990dcd860d29dac733de48717ecdcce02 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 10 Oct 2018 08:53:21 +0400 Subject: [PATCH 055/167] * Sins of the Past - fixed that it can cast cards from any library instead controller's --- Mage.Sets/src/mage/cards/s/SinsOfThePast.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SinsOfThePast.java b/Mage.Sets/src/mage/cards/s/SinsOfThePast.java index 013b5780d7..8e86dc4689 100644 --- a/Mage.Sets/src/mage/cards/s/SinsOfThePast.java +++ b/Mage.Sets/src/mage/cards/s/SinsOfThePast.java @@ -1,7 +1,6 @@ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; @@ -11,32 +10,29 @@ import mage.abilities.effects.common.ExileSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.players.Player; -import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetCardInYourGraveyard; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author emerald000 */ public final class SinsOfThePast extends CardImpl { public SinsOfThePast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}{B}"); // Until end of turn, you may cast target instant or sorcery card from your graveyard without paying its mana cost. If that card would be put into your graveyard this turn, exile it instead. Exile Sins of the Past. this.getSpellAbility().addEffect(new SinsOfThePastEffect()); this.getSpellAbility().addEffect(new ExileSourceEffect()); - this.getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterInstantOrSorceryCard())); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterInstantOrSorceryCard())); } public SinsOfThePast(final SinsOfThePast card) { From a513cf09aef700506f2f8de3c0b97a71156753a5 Mon Sep 17 00:00:00 2001 From: jmharmon <37360760+jmharmon@users.noreply.github.com> Date: Tue, 9 Oct 2018 21:56:18 -0700 Subject: [PATCH 056/167] Update SoulStrings.java --- Mage.Sets/src/mage/cards/s/SoulStrings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SoulStrings.java b/Mage.Sets/src/mage/cards/s/SoulStrings.java index b1a70905c3..5ba36a191f 100644 --- a/Mage.Sets/src/mage/cards/s/SoulStrings.java +++ b/Mage.Sets/src/mage/cards/s/SoulStrings.java @@ -27,7 +27,7 @@ public final class SoulStrings extends CardImpl { new ReturnFromGraveyardToHandTargetEffect(), new VariableManaCost() ); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addTarget(new TargetCardInGraveyard(2, new FilterCreatureCard("creature cards from your graveyard"))); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(2, new FilterCreatureCard("creature cards from your graveyard"))); } public SoulStrings(final SoulStrings card) { From 681cb4b66ad847574c6d12f15d147c005dfee30d Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 10 Oct 2018 09:08:32 +0400 Subject: [PATCH 057/167] Fixed missing import --- Mage.Sets/src/mage/cards/s/SoulStrings.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SoulStrings.java b/Mage.Sets/src/mage/cards/s/SoulStrings.java index 5ba36a191f..553e607203 100644 --- a/Mage.Sets/src/mage/cards/s/SoulStrings.java +++ b/Mage.Sets/src/mage/cards/s/SoulStrings.java @@ -8,12 +8,11 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.common.FilterCreatureCard; -import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; /** - * * @author jmharmon */ From 189984d3d69bf1ea6b5286ca40549cf962a229ee Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 10 Oct 2018 15:37:26 +0200 Subject: [PATCH 058/167] DeckEditorPanel - Fixed some existing exceptions. --- .../java/mage/client/cards/DragCardGrid.java | 30 +-- .../mage/client/deckeditor/CardSelector.java | 4 +- .../client/deckeditor/DeckEditorPane.java | 9 +- .../client/deckeditor/DeckEditorPanel.form | 11 +- .../client/deckeditor/DeckEditorPanel.java | 174 +++++++++--------- .../client/util/sets/ConstructedFormats.java | 9 + .../cards/repository/ExpansionRepository.java | 4 + 7 files changed, 127 insertions(+), 114 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java index 7ca2057605..3d388ad926 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java @@ -1,5 +1,15 @@ package mage.client.cards; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import javax.swing.*; import mage.cards.Card; import mage.cards.MageCard; import mage.cards.decks.DeckCardInfo; @@ -20,17 +30,6 @@ import mage.view.CardsView; import org.apache.log4j.Logger; import org.mage.card.arcane.CardRenderer; -import javax.swing.*; -import java.awt.*; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - /** * Created by StravantUser on 2016-09-20. */ @@ -1408,13 +1407,13 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg while (regexMatcher.find()) { String val = regexMatcher.group(1); int colorless_val = Integer.parseInt(val); - + int total_c_pip = 0; - if (pips.get("#c}") != null) { + if (pips.get("#c}") != null) { total_c_pip = pips.get("#c}"); } pips.put("#c}", colorless_val + total_c_pip); - + int cmc_pip_value = 0; if (pips_at_cmcs.get(cmc + "##c}") != null) { cmc_pip_value = pips_at_cmcs.get(cmc + "##c}"); @@ -2032,6 +2031,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } private int getCardWidth() { + if (GUISizeHelper.editorCardDimension == null) { + return 200; + } return (int) (GUISizeHelper.editorCardDimension.width * cardSizeMod); } diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java index 413b087ebd..7935854a1b 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java @@ -1,6 +1,4 @@ - - - /* +/* * CardSelector.java * * Created on Feb 18, 2010, 2:49:03 PM diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPane.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPane.java index 477c1cff45..a61e879b1a 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPane.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPane.java @@ -1,6 +1,4 @@ - - - /* +/* * DeckEditorPane.java * * Created on Dec 17, 2009, 9:21:42 AM @@ -98,14 +96,13 @@ public class DeckEditorPane extends MagePane { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, 885, Short.MAX_VALUE) + .addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, 885, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, 626, Short.MAX_VALUE) + .addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, 626, Short.MAX_VALUE) ); - } public DeckEditorPanel getPanel() { diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.form b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.form index 5065dfbe63..27c3526d49 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.form +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.form @@ -192,6 +192,15 @@ + + + + + + + + + @@ -210,7 +219,7 @@ - + diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 971e45679b..182be367eb 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -1,6 +1,14 @@ - package mage.client.deckeditor; +import java.awt.*; +import java.awt.event.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.*; +import javax.swing.*; +import javax.swing.filechooser.FileFilter; import mage.cards.Card; import mage.cards.Sets; import mage.cards.decks.Deck; @@ -29,18 +37,6 @@ import mage.view.CardView; import mage.view.SimpleCardView; import org.apache.log4j.Logger; -import javax.swing.*; -import javax.swing.Timer; -import javax.swing.filechooser.FileFilter; -import java.awt.*; -import java.awt.event.*; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.*; -import java.util.List; -import java.util.concurrent.*; - /** * @author BetaSteward_at_googlemail.com */ @@ -55,7 +51,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { private UUID tableId; private DeckEditorMode mode; private int timeout; - private Timer countdown; + private javax.swing.Timer countdown; private UpdateDeckTask updateDeckTask; private int timeToSubmit = -1; @@ -75,7 +71,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { jPanel1.setOpaque(false); jSplitPane1.setOpaque(false); restoreDividerLocationsAndDeckAreaSettings(); - countdown = new Timer(1000, + countdown = new javax.swing.Timer(1000, e -> { if (--timeout > 0) { setTimeout(timeout); @@ -209,7 +205,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { this.btnGenDeck.setVisible(false); this.btnImport.setVisible(false); this.btnLoad.setVisible(false); - this.btnNew.setVisible(false); + this.btnNew.setVisible(false); this.btnSubmit.setVisible(false); this.btnSubmitTimer.setVisible(false); this.cardSelector.loadCards(this.bigCard); @@ -456,7 +452,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { CardView cardView = (CardView) event.getSource(); int numberToSet = event.getNumber(); int cardsFound = 0; - List toDelete = new ArrayList<>(); + java.util.List toDelete = new ArrayList<>(); for (Card card : cards) { if (card.getName().equals(cardView.getName()) && Objects.equals(card.getCardNumber(), cardView.getCardNumber()) @@ -689,7 +685,6 @@ public class DeckEditorPanel extends javax.swing.JPanel { btnGenDeck.setText("Generate"); btnGenDeck.setName("btnGenDeck"); btnGenDeck.addActionListener(evt -> btnGenDeckActionPerformed(evt)); - txtTimeRemaining.setEditable(false); txtTimeRemaining.setForeground(java.awt.Color.red); txtTimeRemaining.setHorizontalAlignment(javax.swing.JTextField.CENTER); @@ -699,89 +694,89 @@ public class DeckEditorPanel extends javax.swing.JPanel { jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - /*.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + /*.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jLayeredPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 256, Short.MAX_VALUE))*/ - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(6, 6, 6) - .addComponent(lblDeckName) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtDeckName, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)) - .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(btnSave) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnLoad) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnNew) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnExit)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(btnImport) - .addContainerGap() - .addComponent(btnGenDeck) - .addContainerGap() - .addComponent(btnAddLand) - .addContainerGap() - .addComponent(btnSubmit) - .addContainerGap() - .addComponent(btnSubmitTimer)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(txtTimeRemaining)) - ) - .addContainerGap())); + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(lblDeckName) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDeckName, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)) + .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(btnSave) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnLoad) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnNew) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnExit)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(btnImport) + .addContainerGap() + .addComponent(btnGenDeck) + .addContainerGap() + .addComponent(btnAddLand) + .addContainerGap() + .addComponent(btnSubmit) + .addContainerGap() + .addComponent(btnSubmitTimer)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(txtTimeRemaining)) + ) + .addContainerGap())); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(txtDeckName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblDeckName)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btnSave) - .addComponent(btnLoad) - .addComponent(btnNew) - .addComponent(btnExit)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btnImport) - .addComponent(btnGenDeck) - .addComponent(btnAddLand) - .addComponent(btnSubmit) - .addComponent(btnSubmitTimer)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(txtTimeRemaining)) - //.addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, isShowCardInfo ? 30 : 159, Short.MAX_VALUE) - .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 104, Short.MAX_VALUE) - .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))); + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtDeckName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblDeckName)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnSave) + .addComponent(btnLoad) + .addComponent(btnNew) + .addComponent(btnExit)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnImport) + .addComponent(btnGenDeck) + .addComponent(btnAddLand) + .addComponent(btnSubmit) + .addComponent(btnSubmitTimer)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtTimeRemaining)) + //.addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, isShowCardInfo ? 30 : 159, Short.MAX_VALUE) + .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 104, Short.MAX_VALUE) + .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE))); + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE))); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE)); + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE)); } - private void processAndShowImportErrors(StringBuilder errorMessages){ + private void processAndShowImportErrors(StringBuilder errorMessages) { // show up errors list - if (errorMessages.length() > 0){ + if (errorMessages.length() > 0) { String mes = "Founded problems with deck: \n\n" + errorMessages.toString(); JOptionPane.showMessageDialog(MageFrame.getDesktop(), mes.substring(0, Math.min(1000, mes.length())), "Errors while loading deck", JOptionPane.WARNING_MESSAGE); } @@ -813,7 +808,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } catch (GameException e1) { JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); - }finally { + } finally { MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } @@ -845,7 +840,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } } catch (GameException e1) { JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); - }finally { + } finally { MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } @@ -1063,7 +1058,6 @@ public class DeckEditorPanel extends javax.swing.JPanel { } refreshDeck(); } - // Variables declaration - do not modify//GEN-BEGIN:variables private mage.client.cards.BigCard bigCard; private javax.swing.JButton btnExit; diff --git a/Mage.Client/src/main/java/mage/client/util/sets/ConstructedFormats.java b/Mage.Client/src/main/java/mage/client/util/sets/ConstructedFormats.java index 93efaaafba..ad1351b7f8 100644 --- a/Mage.Client/src/main/java/mage/client/util/sets/ConstructedFormats.java +++ b/Mage.Client/src/main/java/mage/client/util/sets/ConstructedFormats.java @@ -9,6 +9,8 @@ import java.util.Map; import mage.cards.repository.ExpansionInfo; import mage.cards.repository.ExpansionRepository; import mage.constants.SetType; +import static mage.constants.SetType.EXPANSION; +import static mage.constants.SetType.SUPPLEMENTAL; import mage.deck.Standard; /** @@ -64,6 +66,13 @@ public final class ConstructedFormats { underlyingSetCodesPerFormat.put(CUSTOM, new ArrayList<>()); final Map expansionInfo = new HashMap<>(); formats.clear(); // prevent NPE on sorting if this is not the first try + + // Because this is also called in Netbeans Design view, but the object does not exist in that case, + // we have to return here to prevent exception in design view. (Does not hurt at design time) + if (!ExpansionRepository.instance.instanceInitialized) { + return; + } + for (ExpansionInfo set : ExpansionRepository.instance.getAll()) { expansionInfo.put(set.getName(), set); formats.add(set.getName()); diff --git a/Mage/src/main/java/mage/cards/repository/ExpansionRepository.java b/Mage/src/main/java/mage/cards/repository/ExpansionRepository.java index 4ed44d2966..b36b5cc9e9 100644 --- a/Mage/src/main/java/mage/cards/repository/ExpansionRepository.java +++ b/Mage/src/main/java/mage/cards/repository/ExpansionRepository.java @@ -33,6 +33,8 @@ public enum ExpansionRepository { private Dao expansionDao; + public boolean instanceInitialized = false; + ExpansionRepository() { File file = new File("db"); if (!file.exists()) { @@ -48,9 +50,11 @@ public enum ExpansionRepository { TableUtils.createTableIfNotExists(connectionSource, ExpansionInfo.class); expansionDao = DaoManager.createDao(connectionSource, ExpansionInfo.class); + instanceInitialized = true; } catch (SQLException ex) { ex.printStackTrace(); } + } public void add(ExpansionInfo expansion) { From 2367ff59402fb0a09f7b1d4b206b0401f66aafec Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 10 Oct 2018 16:10:54 +0200 Subject: [PATCH 059/167] Fixed a problem that caused netbeans design view to fail. --- .../main/java/mage/client/util/Config.java | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/util/Config.java b/Mage.Client/src/main/java/mage/client/util/Config.java index 466f2ad08c..459ee469b9 100644 --- a/Mage.Client/src/main/java/mage/client/util/Config.java +++ b/Mage.Client/src/main/java/mage/client/util/Config.java @@ -1,4 +1,3 @@ - package mage.client.util; import java.io.File; @@ -33,38 +32,41 @@ public final class Config { static { Properties p = new Properties(); - try(FileInputStream fis =new FileInputStream(new File("config/config.properties"))) { + boolean fileFound = true; + try (FileInputStream fis = new FileInputStream(new File("config/config.properties"))) { p.load(fis); } catch (IOException ex) { - logger.fatal("Config error ", ex); + fileFound = false; } - serverName = p.getProperty("server-name"); - port = Integer.parseInt(p.getProperty("port")); - remoteServer = p.getProperty("remote-server"); - cardScalingFactor = Double.valueOf(p.getProperty("card-scaling-factor")); - cardScalingFactorEnlarged = Double.valueOf(p.getProperty("card-scaling-factor-enlarged")); - handScalingFactor = Double.valueOf(p.getProperty("hand-scaling-factor")); - defaultGameType = p.getProperty("default-game-type", "Human"); - defaultDeckPath = p.getProperty("default-deck-path"); - defaultOtherPlayerIndex = p.getProperty("default-other-player-index"); - defaultComputerName = p.getProperty("default-computer-name"); + if (fileFound) { + serverName = p.getProperty("server-name"); + port = Integer.parseInt(p.getProperty("port")); + remoteServer = p.getProperty("remote-server"); + cardScalingFactor = Double.valueOf(p.getProperty("card-scaling-factor")); + cardScalingFactorEnlarged = Double.valueOf(p.getProperty("card-scaling-factor-enlarged")); + handScalingFactor = Double.valueOf(p.getProperty("hand-scaling-factor")); + defaultGameType = p.getProperty("default-game-type", "Human"); + defaultDeckPath = p.getProperty("default-deck-path"); + defaultOtherPlayerIndex = p.getProperty("default-other-player-index"); + defaultComputerName = p.getProperty("default-computer-name"); - dimensions = new CardDimensions(cardScalingFactor); - dimensionsEnlarged = new CardDimensions(cardScalingFactorEnlarged); -// activate instead this part, to run the UI editor for some panels without error -// serverName = "localhost"; -// port = 17171; -// remoteServer = "mage-server"; -// cardScalingFactor = 0.4; -// cardScalingFactorEnlarged = 0.5; -// handScalingFactor = 1.3; -// defaultGameType = p.getProperty("default-game-type", "Human"); -// defaultDeckPath = ""; -// defaultOtherPlayerIndex = "1"; -// defaultComputerName = "Computer"; -// -// dimensions = new CardDimensions(cardScalingFactor); -// dimensionsEnlarged = new CardDimensions(cardScalingFactorEnlarged); + dimensions = new CardDimensions(cardScalingFactor); + dimensionsEnlarged = new CardDimensions(cardScalingFactorEnlarged); + } else { // Take some default valies for netbeans design view + serverName = "localhost"; + port = 17171; + remoteServer = "mage-server"; + cardScalingFactor = 0.4; + cardScalingFactorEnlarged = 0.5; + handScalingFactor = 1.3; + defaultGameType = p.getProperty("default-game-type", "Human"); + defaultDeckPath = ""; + defaultOtherPlayerIndex = "1"; + defaultComputerName = "AI Computer"; + + dimensions = new CardDimensions(cardScalingFactor); + dimensionsEnlarged = new CardDimensions(cardScalingFactorEnlarged); + } } From 55ddd19be6dcfaeb0e0b8314885c7afa5af2ae52 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 10 Oct 2018 16:01:55 -0400 Subject: [PATCH 060/167] fixed Beamsplitter Mage being able to target opposing creatures with copied spells --- Mage.Sets/src/mage/cards/b/BeamsplitterMage.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BeamsplitterMage.java b/Mage.Sets/src/mage/cards/b/BeamsplitterMage.java index 0cd6c16ea0..30853e7e8b 100644 --- a/Mage.Sets/src/mage/cards/b/BeamsplitterMage.java +++ b/Mage.Sets/src/mage/cards/b/BeamsplitterMage.java @@ -1,19 +1,19 @@ package mage.cards.b; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.OneShotEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -23,8 +23,9 @@ import mage.target.Target; import mage.target.TargetPermanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class BeamsplitterMage extends CardImpl { @@ -156,7 +157,7 @@ class BeamsplitterMageEffect extends OneShotEffect { if (usedTarget == null) { return false; } - FilterPermanent filter = new BeamsplitterMageFilter(usedTarget, source.getSourceId()); + FilterPermanent filter = new BeamsplitterMageFilter(usedTarget, source.getSourceId(), source.getControllerId()); Target target1 = new TargetPermanent(filter); target1.setNotTarget(true); if (controller.choose(outcome, target1, source.getSourceId(), game)) { @@ -199,10 +200,11 @@ class BeamsplitterMageFilter extends FilterControlledPermanent { private final Target target; private final UUID notId; - public BeamsplitterMageFilter(Target target, UUID notId) { + public BeamsplitterMageFilter(Target target, UUID notId, UUID controllerId) { super("creature this spell could target"); this.target = target; this.notId = notId; + this.add(new ControllerIdPredicate(controllerId)); } public BeamsplitterMageFilter(final BeamsplitterMageFilter filter) { From 9e411228133bbe1059a7a8348e5c08894629c4cf Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 10 Oct 2018 17:14:10 -0400 Subject: [PATCH 061/167] Implemented Mob Mentality --- Mage.Sets/src/mage/cards/m/MobMentality.java | 111 +++++++++++++++++++ Mage.Sets/src/mage/sets/Visions.java | 1 + 2 files changed, 112 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MobMentality.java diff --git a/Mage.Sets/src/mage/cards/m/MobMentality.java b/Mage.Sets/src/mage/cards/m/MobMentality.java new file mode 100644 index 0000000000..e00596f1a3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MobMentality.java @@ -0,0 +1,111 @@ +package mage.cards.m; + +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.AttackingCreatureCount; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MobMentality extends CardImpl { + + public MobMentality(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature has trample. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA))); + + // Whenever all non-Wall creatures you control attack, enchanted creature gets +X/+0 until end of turn, where X is the number of attacking creatures. + this.addAbility(new MobMentalityTriggeredAbility()); + } + + public MobMentality(final MobMentality card) { + super(card); + } + + @Override + public MobMentality copy() { + return new MobMentality(this); + } +} + +class MobMentalityTriggeredAbility extends TriggeredAbilityImpl { + MobMentalityTriggeredAbility() { + super(Zone.BATTLEFIELD, new BoostTargetEffect(new AttackingCreatureCount(), new StaticValue(0), Duration.EndOfTurn, true)); + } + + private MobMentalityTriggeredAbility(final MobMentalityTriggeredAbility ability) { + super(ability); + } + + @Override + public MobMentalityTriggeredAbility copy() { + return new MobMentalityTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!game.getCombat().getAttackingPlayerId().equals(getControllerId())) { + return false; + } + Permanent aura = game.getPermanent(getSourceId()); + if (aura == null) { + return false; + } + Permanent creature = game.getPermanent(aura.getAttachedTo()); + if (creature == null) { + return false; + } + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(creature, game)); + } + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(getControllerId())) { + if (permanent.isCreature() + && !permanent.hasSubtype(SubType.WALL, game) + && !permanent.isAttacking()) { + return false; + } + } + return true; + } + + @Override + public String getRule() { + return "Whenever all non-Wall creatures you control attack, " + + "enchanted creature gets +X/+0 until end of turn, " + + "where X is the number of attacking creatures."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index ea27845253..eaf27a65d3 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -105,6 +105,7 @@ public final class Visions extends ExpansionSet { cards.add(new SetCardInfo("Magma Mine", 149, Rarity.UNCOMMON, mage.cards.m.MagmaMine.class)); cards.add(new SetCardInfo("Man-o'-War", 37, Rarity.COMMON, mage.cards.m.ManOWar.class)); cards.add(new SetCardInfo("Miraculous Recovery", 13, Rarity.UNCOMMON, mage.cards.m.MiraculousRecovery.class)); + cards.add(new SetCardInfo("Mob Mentality", 88, Rarity.UNCOMMON, mage.cards.m.MobMentality.class)); cards.add(new SetCardInfo("Mortal Wound", 113, Rarity.COMMON, mage.cards.m.MortalWound.class)); cards.add(new SetCardInfo("Mundungu", 132, Rarity.UNCOMMON, mage.cards.m.Mundungu.class)); cards.add(new SetCardInfo("Mystic Veil", 38, Rarity.COMMON, mage.cards.m.MysticVeil.class)); From fde0ba284a1075596ef055d4de0fbe8279b30c07 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 10 Oct 2018 23:17:10 +0200 Subject: [PATCH 062/167] * Glarecaster - Fixed that its redirect ability allows for multiple redirects not only if damage is dealt at the same time (fixes #5368). --- .../replacement/redirect/GlarecasterTest.java | 48 +++++++++++++++++++ .../abilities/effects/RedirectionEffect.java | 3 +- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/replacement/redirect/GlarecasterTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/redirect/GlarecasterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/redirect/GlarecasterTest.java new file mode 100644 index 0000000000..817761420f --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/redirect/GlarecasterTest.java @@ -0,0 +1,48 @@ +package org.mage.test.cards.replacement.redirect; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class GlarecasterTest extends CardTestPlayerBase { + + /** + * I can activate Glarecaster's redirection ability, immediately cast two + * Lightning Bolts on it and both get redirected towards the chosen target. + * If I pass until the next step and cast another Bolt on it, it's not being + * redirected anymore. + * + */ + @Test + public void testTwoTimesInstantSpellDamage() { + addCard(Zone.HAND, playerA, "Lightning Bolt", 2); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + + // Flying + // {5}{W}: The next time damage would be dealt to Glarecaster and/or you this turn, that damage is dealt to any target instead. + addCard(Zone.BATTLEFIELD, playerB, "Glarecaster"); // Creature 3/3 + addCard(Zone.BATTLEFIELD, playerB, "Plains", 6); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{5}{W}: The next time damage would be dealt to", playerA); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Glarecaster"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerA, "Lightning Bolt", 2); + + assertPermanentCount(playerB, "Glarecaster", 1); + + assertLife(playerA, 17); + assertLife(playerB, 17); + + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/RedirectionEffect.java b/Mage/src/main/java/mage/abilities/effects/RedirectionEffect.java index afea25b950..262d7ab3be 100644 --- a/Mage/src/main/java/mage/abilities/effects/RedirectionEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/RedirectionEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects; import mage.MageObject; @@ -47,6 +46,7 @@ public abstract class RedirectionEffect extends ReplacementEffectImpl { this.redirectTarget = effect.redirectTarget; this.amountToRedirect = effect.amountToRedirect; this.usageType = effect.usageType; + this.applyEffectsCounter = effect.applyEffectsCounter; } @Override @@ -80,6 +80,7 @@ public abstract class RedirectionEffect extends ReplacementEffectImpl { if (applyEffectsCounter > 0) { if (applyEffectsCounter < game.getState().getApplyEffectsCounter()) { this.discard(); + return false; } } else { applyEffectsCounter = game.getState().getApplyEffectsCounter(); From b0395f704f2fa666cea7680fe429a0efb85680e4 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 10 Oct 2018 23:35:03 +0200 Subject: [PATCH 063/167] * Ob Nixilis, Unshacked - Fixed that it doesn't triggered on failing to find a card (fixes #5367). --- Mage/src/main/java/mage/players/PlayerImpl.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 2659dfd145..42eebc64e7 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -2463,13 +2463,14 @@ public abstract class PlayerImpl implements Player, Serializable { for (UUID targetId : newTarget.getTargets()) { target.add(targetId, game); } - if (triggerEvents) { - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, targetPlayerId, playerId)); - } + } else if (targetPlayerId.equals(playerId) && handleLibraryCastableCards(library, game, targetPlayerId)) { // for handling Panglacial Wurm newTarget.clearChosen(); continue; } + if (triggerEvents) { + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, targetPlayerId, playerId)); + } break; } while (true); return true; From c95f5b55fc5273d1d192234877a9985b908a9bca Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 10 Oct 2018 20:35:24 -0400 Subject: [PATCH 064/167] Implemented Betrothed of Fire --- .../src/mage/cards/b/BetrothedOfFire.java | 71 +++++++++++++++++++ Mage.Sets/src/mage/sets/Weatherlight.java | 1 + 2 files changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BetrothedOfFire.java diff --git a/Mage.Sets/src/mage/cards/b/BetrothedOfFire.java b/Mage.Sets/src/mage/cards/b/BetrothedOfFire.java new file mode 100644 index 0000000000..95fbfb8440 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BetrothedOfFire.java @@ -0,0 +1,71 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeAttachedCost; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BetrothedOfFire extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("an untapped creature"); + + static { + filter.add(Predicates.not(new TappedPredicate())); + } + + public BetrothedOfFire(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Sacrifice an untapped creature: Enchanted creature gets +2/+0 until end of turn. + this.addAbility(new SimpleActivatedAbility( + new BoostEnchantedEffect(2, 0, Duration.EndOfTurn), + new SacrificeTargetCost(new TargetControlledPermanent(filter)) + )); + + // Sacrifice enchanted creature: Creatures you control get +2/+0 until end of turn. + this.addAbility(new SimpleActivatedAbility( + new BoostControlledEffect(2, 0, Duration.EndOfTurn), + new SacrificeAttachedCost() + )); + } + + public BetrothedOfFire(final BetrothedOfFire card) { + super(card); + } + + @Override + public BetrothedOfFire copy() { + return new BetrothedOfFire(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Weatherlight.java b/Mage.Sets/src/mage/sets/Weatherlight.java index 01abb9f2b1..88f32d096d 100644 --- a/Mage.Sets/src/mage/sets/Weatherlight.java +++ b/Mage.Sets/src/mage/sets/Weatherlight.java @@ -49,6 +49,7 @@ public final class Weatherlight extends ExpansionSet { cards.add(new SetCardInfo("Benalish Infantry", 8, Rarity.COMMON, mage.cards.b.BenalishInfantry.class)); cards.add(new SetCardInfo("Benalish Knight", 9, Rarity.COMMON, mage.cards.b.BenalishKnight.class)); cards.add(new SetCardInfo("Benalish Missionary", 10, Rarity.COMMON, mage.cards.b.BenalishMissionary.class)); + cards.add(new SetCardInfo("Betrothed of Fire", 89, Rarity.COMMON, mage.cards.b.BetrothedOfFire.class)); cards.add(new SetCardInfo("Bloodrock Cyclops", 90, Rarity.COMMON, mage.cards.b.BloodrockCyclops.class)); cards.add(new SetCardInfo("Blossoming Wreath", 120, Rarity.COMMON, mage.cards.b.BlossomingWreath.class)); cards.add(new SetCardInfo("Bogardan Firefiend", 91, Rarity.COMMON, mage.cards.b.BogardanFirefiend.class)); From 34e401254004ed733060b83d269861f1dcf9f16b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 10 Oct 2018 21:05:01 -0400 Subject: [PATCH 065/167] Implemented Mistfolk --- Mage.Sets/src/mage/cards/m/Mistfolk.java | 83 +++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + .../mage/abilities/keyword/MentorAbility.java | 6 +- 3 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/m/Mistfolk.java diff --git a/Mage.Sets/src/mage/cards/m/Mistfolk.java b/Mage.Sets/src/mage/cards/m/Mistfolk.java new file mode 100644 index 0000000000..497feb0ec5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/Mistfolk.java @@ -0,0 +1,83 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.SpellAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterSpell; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.target.Target; +import mage.target.TargetSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Mistfolk extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("spell that this creature"); + + static { + filter.add(MistfolkPredicate.instance); + } + + public Mistfolk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}"); + + this.subtype.add(SubType.ILLUSION); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // {U}: Counter target spell that targets Mistfolk. + Ability ability = new SimpleActivatedAbility( + new CounterTargetEffect() + .setText("counter target spell that targets {this}"), + new ManaCostsImpl("{U}") + ); + ability.addTarget(new TargetSpell(filter)); + this.addAbility(ability); + } + + public Mistfolk(final Mistfolk card) { + super(card); + } + + @Override + public Mistfolk copy() { + return new Mistfolk(this); + } +} + +enum MistfolkPredicate implements ObjectSourcePlayerPredicate> { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + Permanent sourceObject = game.getPermanent(input.getSourceId()); + if (sourceObject == null || input.getObject() == null) { + return false; + } + for (SpellAbility spellAbility : input.getObject().getSpellAbilities()) { + for (Mode mode : spellAbility.getModes().values()) { + for (Target target : spellAbility.getTargets()) { + if (target.getTargets().contains(input.getSourceId())) { + return true; + } + } + } + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index fc2e781f9c..2112294e3b 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -215,6 +215,7 @@ public final class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Mind Warp", 148, Rarity.UNCOMMON, mage.cards.m.MindWarp.class)); cards.add(new SetCardInfo("Minion of Leshrac", 150, Rarity.RARE, mage.cards.m.MinionOfLeshrac.class)); cards.add(new SetCardInfo("Minion of Tevesh Szat", 151, Rarity.RARE, mage.cards.m.MinionOfTeveshSzat.class)); + cards.add(new SetCardInfo("Mistfolk", 84, Rarity.COMMON, mage.cards.m.Mistfolk.class)); cards.add(new SetCardInfo("Mole Worms", 152, Rarity.UNCOMMON, mage.cards.m.MoleWorms.class)); cards.add(new SetCardInfo("Monsoon", 298, Rarity.RARE, mage.cards.m.Monsoon.class)); cards.add(new SetCardInfo("Moor Fiend", 153, Rarity.COMMON, mage.cards.m.MoorFiend.class)); diff --git a/Mage/src/main/java/mage/abilities/keyword/MentorAbility.java b/Mage/src/main/java/mage/abilities/keyword/MentorAbility.java index bd579657da..85f700357f 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MentorAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MentorAbility.java @@ -13,7 +13,6 @@ import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; /** - * * @author TheElk801 */ public class MentorAbility extends AttacksTriggeredAbility { @@ -22,7 +21,7 @@ public class MentorAbility extends AttacksTriggeredAbility { static { filter.add(new AttackingPredicate()); - filter.add(new MentorAbilityPredicate()); + filter.add(MentorAbilityPredicate.instance); } public MentorAbility() { @@ -46,7 +45,8 @@ public class MentorAbility extends AttacksTriggeredAbility { } -class MentorAbilityPredicate implements ObjectSourcePlayerPredicate> { +enum MentorAbilityPredicate implements ObjectSourcePlayerPredicate> { + instance; @Override public boolean apply(ObjectSourcePlayer input, Game game) { From 0df97e5d4b97fbd932cd32166213ec453eff143b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 12 Oct 2018 22:17:24 +0400 Subject: [PATCH 066/167] * Server: fixed error on missing xmage.properties file settings on feedback receive; --- .../src/main/java/mage/utils/properties/PropertiesUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Mage.Common/src/main/java/mage/utils/properties/PropertiesUtil.java b/Mage.Common/src/main/java/mage/utils/properties/PropertiesUtil.java index 0a220e12fd..17fe10e05b 100644 --- a/Mage.Common/src/main/java/mage/utils/properties/PropertiesUtil.java +++ b/Mage.Common/src/main/java/mage/utils/properties/PropertiesUtil.java @@ -21,7 +21,11 @@ public final class PropertiesUtil { static { try (InputStream in = PropertiesUtil.class.getResourceAsStream("/xmage.properties")) { - properties.load(in); + if(in != null) { + properties.load(in); + } else { + logger.warn("No xmage.properties were found"); + } } catch (FileNotFoundException fnfe) { logger.warn("No xmage.properties were found on classpath"); } catch (IOException e) { From 9a4fb4adb18407622e3e1e799905ed826beb513d Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 12 Oct 2018 22:19:45 +0400 Subject: [PATCH 067/167] Tests: fixed error on missing db files; --- .../java/org/mage/plugins/card/images/ImageCache.java | 1 + .../src/test/java/org/mage/test/load/LoadTest.java | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java index ffe80ecdf5..2edf005832 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java @@ -409,6 +409,7 @@ public final class ImageCache { // legitimate, happens when a card has no image return null; } catch (ComputationException ex) { + // too low memory if (ex.getCause() instanceof NullPointerException) { return null; } diff --git a/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java index afe179f7c7..636305a79d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java @@ -10,6 +10,7 @@ import mage.cards.decks.DeckCardInfo; import mage.cards.decks.DeckCardLists; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; +import mage.cards.repository.CardScanner; import mage.constants.*; import mage.game.match.MatchOptions; import mage.player.ai.ComputerPlayer; @@ -21,9 +22,7 @@ import mage.remote.SessionImpl; import mage.util.RandomUtil; import mage.view.*; import org.apache.log4j.Logger; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.*; /** * Intended to test Mage server under different load patterns. @@ -45,6 +44,12 @@ public class LoadTest { private static final String TEST_PROXY_TYPE = "None"; private static final String TEST_USER_NAME = "user"; + @BeforeClass + public static void initDatabase() { + // recreate missing cards db + CardScanner.scan(); + } + @Test public void test_CreateRandomDeck() { From 2bd5d0ddf6fc0d79c58ffd76c5575e9996cac963 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 13 Oct 2018 01:11:26 +0400 Subject: [PATCH 068/167] * UI: Fixed wrong game selection by double click on tables list (#5239); --- Mage.Client/src/main/java/mage/client/table/TablesPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index d28badf2f7..59c4d88805 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -326,7 +326,7 @@ public class TablesPanel extends javax.swing.JPanel { table.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - int row = table.rowAtPoint(e.getPoint()); + int row = table.convertRowIndexToModel(table.getSelectedRow()); if (e.getClickCount() == 2 && row != -1) { action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + row)); } From 44b2e7f84ebf11bc4c5854208897304678922464 Mon Sep 17 00:00:00 2001 From: L_J Date: Sat, 13 Oct 2018 14:14:57 +0200 Subject: [PATCH 069/167] Implemented Invasion cards --- Mage.Sets/src/mage/cards/b/BendOrBreak.java | 199 ++++++++++++++++++ Mage.Sets/src/mage/cards/d/DeathOrGlory.java | 129 ++++++++++++ Mage.Sets/src/mage/cards/f/FightOrFlight.java | 109 ++++++++++ .../src/mage/cards/p/PulseOfLlanowar.java | 98 +++++++++ .../src/mage/cards/s/SamiteMinistration.java | 90 ++++++++ Mage.Sets/src/mage/cards/s/StandOrFall.java | 133 ++++++++++++ .../src/mage/cards/v/VigorousCharge.java | 95 +++++++++ Mage.Sets/src/mage/sets/Invasion.java | 7 + 8 files changed, 860 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BendOrBreak.java create mode 100644 Mage.Sets/src/mage/cards/d/DeathOrGlory.java create mode 100644 Mage.Sets/src/mage/cards/f/FightOrFlight.java create mode 100644 Mage.Sets/src/mage/cards/p/PulseOfLlanowar.java create mode 100644 Mage.Sets/src/mage/cards/s/SamiteMinistration.java create mode 100644 Mage.Sets/src/mage/cards/s/StandOrFall.java create mode 100644 Mage.Sets/src/mage/cards/v/VigorousCharge.java diff --git a/Mage.Sets/src/mage/cards/b/BendOrBreak.java b/Mage.Sets/src/mage/cards/b/BendOrBreak.java new file mode 100644 index 0000000000..e7bdfa74f9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BendOrBreak.java @@ -0,0 +1,199 @@ + +package mage.cards.b; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.FilterPlayer; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.other.PlayerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.players.PlayerList; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.TargetPlayer; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author LevelX2 & L_J + */ +public final class BendOrBreak extends CardImpl { + + public BendOrBreak(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); + + // Each player separates all nontoken lands they control into two piles. For each player, one of their piles is chosen by one of their opponents of their choice. Destroy all lands in the chosen piles. Tap all lands in the other piles. + this.getSpellAbility().addEffect(new BendOrBreakEffect()); + } + + public BendOrBreak(final BendOrBreak card) { + super(card); + } + + @Override + public BendOrBreak copy() { + return new BendOrBreak(this); + } +} + +class BendOrBreakEffect extends OneShotEffect { + + + public BendOrBreakEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Each player separates all nontoken lands they control into two piles. For each player, one of their piles is chosen by one of their opponents of their choice. Destroy all lands in the chosen piles. Tap all lands in the other piles"; + } + + public BendOrBreakEffect(final BendOrBreakEffect effect) { + super(effect); + } + + @Override + public BendOrBreakEffect copy() { + return new BendOrBreakEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + + // Map of players and their piles + Map>> playerPermanents = new LinkedHashMap<>(); + + PlayerList playerList = game.getState().getPlayerList().copy(); + while (!playerList.get().equals(source.getControllerId()) && controller.canRespond()) { + playerList.getNext(); + } + Player currentPlayer = game.getPlayer(playerList.get()); + Player nextPlayer; + UUID firstNextPlayer = null; + + while (!getNextPlayerInDirection(true, playerList, game).equals(firstNextPlayer) && controller.canRespond()) { + nextPlayer = game.getPlayer(playerList.get()); + if (nextPlayer == null) { + return false; + } + if (firstNextPlayer == null) { + firstNextPlayer = nextPlayer.getId(); + } + if (!nextPlayer.canRespond()) { + continue; + } + // Each player separates all nontoken lands they control into two piles + if (currentPlayer != null && game.getState().getPlayersInRange(controller.getId(), game).contains(currentPlayer.getId())) { + List firstPile = new ArrayList<>(); + List secondPile = new ArrayList<>(); + FilterControlledLandPermanent filter = new FilterControlledLandPermanent("lands you control to assign to the first pile (lands not chosen will be assigned to the second pile)"); + TargetPermanent target = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true); + if (target.canChoose(source.getSourceId(), currentPlayer.getId(), game)) { + if (currentPlayer.chooseTarget(Outcome.Neutral, target, source, game)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, currentPlayer.getId(), game)) { + if (target.getTargets().contains(permanent.getId())) { + firstPile.add(permanent); + } else { + secondPile.add(permanent); + } + } + } + + StringBuilder sb = new StringBuilder("First pile of ").append(currentPlayer.getLogName()).append(": "); + sb.append(firstPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", "))); + + game.informPlayers(sb.toString()); + + sb = new StringBuilder("Second pile of ").append(currentPlayer.getLogName()).append(": "); + sb.append(secondPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", "))); + + game.informPlayers(sb.toString()); + } + List> playerPiles = new ArrayList<>(); + playerPiles.add(firstPile); + playerPiles.add(secondPile); + playerPermanents.put(currentPlayer.getId(), playerPiles); + } + currentPlayer = nextPlayer; + } + + // For each player, one of their piles is chosen by one of their opponents of their choice + for (Map.Entry>> playerPiles : playerPermanents.entrySet()) { + Player player = game.getPlayer(playerPiles.getKey()); + if (player != null) { + FilterPlayer filter = new FilterPlayer("opponent"); + List opponentPredicates = new ArrayList<>(); + for (UUID opponentId : game.getOpponents(player.getId())) { + opponentPredicates.add(new PlayerIdPredicate(opponentId)); + } + filter.add(Predicates.or(opponentPredicates)); + Target target = new TargetPlayer(1, 1, true, filter); + target.setTargetController(player.getId()); + target.setAbilityController(source.getControllerId()); + if (player.chooseTarget(outcome, target, source, game)) { + Player chosenOpponent = game.getPlayer(target.getFirstTarget()); + if (chosenOpponent != null) { + List firstPile = playerPiles.getValue().get(0); + List secondPile = playerPiles.getValue().get(1); + game.informPlayers(player.getLogName() + " chose " + chosenOpponent.getLogName() + " to choose his pile"); + if (chosenOpponent.choosePile(outcome, "Piles of " + player.getName(), firstPile, secondPile, game)) { + List> lists = playerPiles.getValue(); + lists.clear(); + lists.add(firstPile); + lists.add(secondPile); + game.informPlayers(player.getLogName() + " will have their first pile destroyed"); + } else { + List> lists = playerPiles.getValue(); + lists.clear(); + lists.add(secondPile); + lists.add(firstPile); + game.informPlayers(player.getLogName() + " will have their second pile destroyed"); + } + } + } + } + } + // Destroy all lands in the chosen piles. Tap all lands in the other piles + for (Map.Entry>> playerPiles : playerPermanents.entrySet()) { + Player player = game.getPlayer(playerPiles.getKey()); + if (player != null) { + List pileToSac = playerPiles.getValue().get(0); + List pileToTap = playerPiles.getValue().get(1); + for (Permanent permanent : pileToSac) { + if (permanent != null) { + permanent.destroy(source.getSourceId(), game, false); + } + } + for (Permanent permanent : pileToTap) { + if (permanent != null) { + permanent.tap(game); + } + } + } + } + return true; + } + return false; + } + + private UUID getNextPlayerInDirection(boolean left, PlayerList playerList, Game game) { + UUID nextPlayerId; + if (left) { + nextPlayerId = playerList.getNext(); + } else { + nextPlayerId = playerList.getPrevious(); + } + return nextPlayerId; + } +} diff --git a/Mage.Sets/src/mage/cards/d/DeathOrGlory.java b/Mage.Sets/src/mage/cards/d/DeathOrGlory.java new file mode 100644 index 0000000000..1417f0bd85 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeathOrGlory.java @@ -0,0 +1,129 @@ + +package mage.cards.d; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; + +/** + * + * @author L_J + */ +public final class DeathOrGlory extends CardImpl { + + public DeathOrGlory(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W}"); + + // Separate all creature cards in your graveyard into two piles. Exile the pile of an opponent’s choice and return the other to the battlefield. + this.getSpellAbility().addEffect(new DeathOrGloryEffect()); + } + + public DeathOrGlory(final DeathOrGlory card) { + super(card); + } + + @Override + public DeathOrGlory copy() { + return new DeathOrGlory(this); + } +} + +class DeathOrGloryEffect extends OneShotEffect { + + DeathOrGloryEffect() { + super(Outcome.Benefit); + this.staticText = "Separate all creature cards in your graveyard into two piles. Exile the pile of an opponent’s choice and return the other to the battlefield"; + } + + DeathOrGloryEffect(final DeathOrGloryEffect effect) { + super(effect); + } + + @Override + public DeathOrGloryEffect copy() { + return new DeathOrGloryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards cards = new CardsImpl(); + cards.addAll(controller.getGraveyard().getCards(new FilterCreatureCard(), game)); + if (!cards.isEmpty()) { + TargetCard targetCards = new TargetCard(0, cards.size(), Zone.EXILED, new FilterCard("cards to put in the first pile")); + List pile1 = new ArrayList<>(); + if (controller.choose(Outcome.Neutral, cards, targetCards, game)) { + List targets = targetCards.getTargets(); + for (UUID targetId : targets) { + Card card = cards.get(targetId, game); + if (card != null) { + pile1.add(card); + cards.remove(card); + } + } + } + List pile2 = new ArrayList<>(); + pile2.addAll(cards.getCards(game)); + + StringBuilder sb = new StringBuilder("First pile of ").append(controller.getLogName()).append(": "); + sb.append(pile1.stream().map(Card::getLogName).collect(Collectors.joining(", "))); + game.informPlayers(sb.toString()); + + sb = new StringBuilder("Second pile of ").append(controller.getLogName()).append(": "); + sb.append(pile2.stream().map(Card::getLogName).collect(Collectors.joining(", "))); + game.informPlayers(sb.toString()); + + Set opponents = game.getOpponents(source.getControllerId()); + if (!opponents.isEmpty()) { + Player opponent = game.getPlayer(opponents.iterator().next()); + if (opponents.size() > 1) { + Target targetOpponent = new TargetOpponent(true); + if (controller.chooseTarget(Outcome.Neutral, targetOpponent, source, game)) { + opponent = game.getPlayer(targetOpponent.getFirstTarget()); + game.informPlayers(controller.getLogName() + " chose " + opponent.getLogName() + " to choose his pile"); + } + } + if (opponent != null) { + boolean choice = opponent.choosePile(outcome, "Choose a pile to put onto the battlefield.", pile1, pile2, game); + + Zone pile1Zone = Zone.EXILED; + Zone pile2Zone = Zone.BATTLEFIELD; + if (choice) { + pile1Zone = Zone.BATTLEFIELD; + pile2Zone = Zone.EXILED; + } + Set pile1Set = new HashSet<>(); + Set pile2Set = new HashSet<>(); + pile1Set.addAll(pile1); + pile2Set.addAll(pile2); + controller.moveCards(pile1Set, pile1Zone, source, game, false, false, false, null); + controller.moveCards(pile2Set, pile2Zone, source, game, false, false, false, null); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/f/FightOrFlight.java b/Mage.Sets/src/mage/cards/f/FightOrFlight.java new file mode 100644 index 0000000000..69e34a94fd --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FightOrFlight.java @@ -0,0 +1,109 @@ + +package mage.cards.f; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.combat.CantAttackTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 & L_J + */ +public final class FightOrFlight extends CardImpl { + + public FightOrFlight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}"); + + // At the beginning of combat on each opponent’s turn, separate all creatures that player controls into two piles. Only creatures in the pile of their choice can attack this turn. + this.addAbility(new BeginningOfCombatTriggeredAbility(new FightOrFlightEffect(), TargetController.OPPONENT, false)); + } + + public FightOrFlight(final FightOrFlight card) { + super(card); + } + + @Override + public FightOrFlight copy() { + return new FightOrFlight(this); + } +} + +class FightOrFlightEffect extends OneShotEffect { + + public FightOrFlightEffect() { + super(Outcome.Detriment); + this.staticText = "separate all creatures that player controls into two piles. Only creatures in the pile of their choice can attack this turn"; + } + + public FightOrFlightEffect(final FightOrFlightEffect effect) { + super(effect); + } + + @Override + public FightOrFlightEffect copy() { + return new FightOrFlightEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Player targetPlayer = game.getPlayer(game.getCombat().getAttackingPlayerId()); + if (player != null && targetPlayer != null) { + int count = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURES, targetPlayer.getId(), game); + TargetCreaturePermanent creatures = new TargetCreaturePermanent(0, count, new FilterCreaturePermanent("creatures to put in the first pile"), true); + List pile1 = new ArrayList<>(); + creatures.setRequired(false); + if (player.choose(Outcome.Neutral, creatures, source.getSourceId(), game)) { + List targets = creatures.getTargets(); + for (UUID targetId : targets) { + Permanent p = game.getPermanent(targetId); + if (p != null) { + pile1.add(p); + } + } + } + List pile2 = new ArrayList<>(); + for (Permanent p : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, targetPlayer.getId(), game)) { + if (!pile1.contains(p)) { + pile2.add(p); + } + } + + boolean choice = targetPlayer.choosePile(outcome, "Choose which pile can attack this turn.", pile1, pile2, game); + List chosenPile = choice ? pile2 : pile1; + List otherPile = choice ? pile1 : pile2; + for (Permanent permanent : chosenPile) { + if (permanent != null) { + RestrictionEffect effect = new CantAttackTargetEffect(Duration.EndOfTurn); + effect.setText(""); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + } + } + StringBuilder sb = new StringBuilder("Creatures that can attack this turn: "); + sb.append(otherPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", "))); + game.informPlayers(sb.toString()); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PulseOfLlanowar.java b/Mage.Sets/src/mage/cards/p/PulseOfLlanowar.java new file mode 100644 index 0000000000..e4ae658497 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PulseOfLlanowar.java @@ -0,0 +1,98 @@ + +package mage.cards.p; + +import java.util.UUID; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.mana.AddManaOfAnyColorEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ManaEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author L_J + */ +public final class PulseOfLlanowar extends CardImpl { + + public PulseOfLlanowar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); + + // If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PulseOfLlanowarReplacementEffect())); + } + + public PulseOfLlanowar(final PulseOfLlanowar card) { + super(card); + } + + @Override + public PulseOfLlanowar copy() { + return new PulseOfLlanowar(this); + } +} + +class PulseOfLlanowarReplacementEffect extends ReplacementEffectImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + static { + filter.add(new SupertypePredicate(SuperType.BASIC)); + } + + PulseOfLlanowarReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral); + staticText = "If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type"; + } + + PulseOfLlanowarReplacementEffect(final PulseOfLlanowarReplacementEffect effect) { + super(effect); + } + + @Override + public PulseOfLlanowarReplacementEffect copy() { + return new PulseOfLlanowarReplacementEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + ManaEvent manaEvent = (ManaEvent) event; + Mana mana = manaEvent.getMana(); + new AddManaOfAnyColorEffect(mana.count()).apply(game,source); + mana.setToMana(new Mana(0,0,0,0,0,0,0,0)); + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == EventType.TAPPED_FOR_MANA; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + MageObject mageObject = game.getObject(event.getSourceId()); + if (mageObject != null && mageObject.isLand()) { + Permanent land = game.getPermanent(event.getSourceId()); + return land != null && filter.match(land, game); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SamiteMinistration.java b/Mage.Sets/src/mage/cards/s/SamiteMinistration.java new file mode 100644 index 0000000000..5035bafdaa --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SamiteMinistration.java @@ -0,0 +1,90 @@ + +package mage.cards.s; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.PreventionEffectData; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.TargetSource; + +/** + * + * @author L_J + */ +public final class SamiteMinistration extends CardImpl { + + public SamiteMinistration(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Prevent all damage that would be dealt to you this turn by a source of your choice. Whenever damage from a black or red source is prevented this way this turn, you gain that much life. + this.getSpellAbility().addEffect(new SamiteMinistrationEffect()); + } + + public SamiteMinistration(final SamiteMinistration card) { + super(card); + } + + @Override + public SamiteMinistration copy() { + return new SamiteMinistration(this); + } + +} + +class SamiteMinistrationEffect extends PreventionEffectImpl { + + private final TargetSource targetSource; + + public SamiteMinistrationEffect() { + super(Duration.EndOfTurn, Integer.MAX_VALUE, false); + this.staticText = "Prevent all damage that would be dealt to you this turn by a source of your choice. Whenever damage from a black or red source is prevented this way this turn, you gain that much life"; + this.targetSource = new TargetSource(); + } + + public SamiteMinistrationEffect(final SamiteMinistrationEffect effect) { + super(effect); + this.targetSource = effect.targetSource.copy(); + } + + @Override + public SamiteMinistrationEffect copy() { + return new SamiteMinistrationEffect(this); + } + + @Override + public void init(Ability source, Game game) { + this.targetSource.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), game); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + PreventionEffectData preventionData = preventDamageAction(event, source, game); + MageObject sourceObject = game.getObject(event.getSourceId()); + if (sourceObject.getColor(game).isBlack() || sourceObject.getColor(game).isRed()) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + player.gainLife(preventionData.getPreventedDamage(), game, source); + } + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (super.applies(event, source, game)) { + if (event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(targetSource.getFirstTarget())) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/StandOrFall.java b/Mage.Sets/src/mage/cards/s/StandOrFall.java new file mode 100644 index 0000000000..8bdbcefd8f --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StandOrFall.java @@ -0,0 +1,133 @@ + +package mage.cards.s; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.combat.CantBlockTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 & L_J + */ +public final class StandOrFall extends CardImpl { + + public StandOrFall(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}"); + + // At the beginning of combat on your turn, separate all creatures defending player controls into two piles. Only creatures in the pile of that player’s choice can block this turn. + this.addAbility(new BeginningOfCombatTriggeredAbility(new StandOrFallEffect(), TargetController.YOU, false)); + } + + public StandOrFall(final StandOrFall card) { + super(card); + } + + @Override + public StandOrFall copy() { + return new StandOrFall(this); + } +} + +class StandOrFallEffect extends OneShotEffect { + + public StandOrFallEffect() { + super(Outcome.Detriment); + this.staticText = "separate all creatures defending player controls into two piles. Only creatures in the pile of that player’s choice can block this turn"; + } + + public StandOrFallEffect(final StandOrFallEffect effect) { + super(effect); + } + + @Override + public StandOrFallEffect copy() { + return new StandOrFallEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + // 802.2. As the combat phase starts, the attacking player doesn’t choose an opponent to become the defending player. + // Instead, all the attacking player’s opponents are defending players during the combat phase. + // + // 802.2a Any rule, object, or effect that refers to a “defending player” refers to one specific defending player, not to all of the defending players. + // If an ability of an attacking creature refers to a defending player, or a spell or ability refers to both an attacking creature and a defending player, + // then unless otherwise specified, the defending player it’s referring to is the player that creature was attacking at the time it became an attacking + // creature that combat, or the controller of the planeswalker that creature was attacking at the time it became an attacking creature that combat. If a spell or ability + // could apply to multiple attacking creatures, the appropriate defending player is individually determined for each of those attacking creatures. + // If there are multiple defending players that could be chosen, the controller of the spell or ability chooses one. + // + // https://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/756140-stand-or-fall-mechanics + Player player = game.getPlayer(source.getControllerId()); + Set opponents = game.getOpponents(source.getControllerId()); + if (!opponents.isEmpty()) { + Player targetPlayer = game.getPlayer(opponents.iterator().next()); + if (opponents.size() > 1) { + TargetOpponent targetOpponent = new TargetOpponent(true); + if (player.chooseTarget(Outcome.Neutral, targetOpponent, source, game)) { + targetPlayer = game.getPlayer(targetOpponent.getFirstTarget()); + game.informPlayers(player.getLogName() + " chose " + targetPlayer.getLogName() + " as the defending player"); + } + } + + if (player != null && targetPlayer != null) { + int count = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURES, targetPlayer.getId(), game); + TargetCreaturePermanent creatures = new TargetCreaturePermanent(0, count, new FilterCreaturePermanent("creatures to put in the first pile"), true); + List pile1 = new ArrayList<>(); + creatures.setRequired(false); + if (player.choose(Outcome.Neutral, creatures, source.getSourceId(), game)) { + List targets = creatures.getTargets(); + for (UUID targetId : targets) { + Permanent p = game.getPermanent(targetId); + if (p != null) { + pile1.add(p); + } + } + } + List pile2 = new ArrayList<>(); + for (Permanent p : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, targetPlayer.getId(), game)) { + if (!pile1.contains(p)) { + pile2.add(p); + } + } + + boolean choice = targetPlayer.choosePile(outcome, "Choose which pile can block this turn.", pile1, pile2, game); + List chosenPile = choice ? pile2 : pile1; + List otherPile = choice ? pile1 : pile2; + for (Permanent permanent : chosenPile) { + if (permanent != null) { + RestrictionEffect effect = new CantBlockTargetEffect(Duration.EndOfTurn); + effect.setText(""); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + } + } + StringBuilder sb = new StringBuilder("Creatures that can block this turn: "); + sb.append(otherPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", "))); + game.informPlayers(sb.toString()); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/v/VigorousCharge.java b/Mage.Sets/src/mage/cards/v/VigorousCharge.java new file mode 100644 index 0000000000..fccee6d9cb --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VigorousCharge.java @@ -0,0 +1,95 @@ + +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.condition.LockedInCondition; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.KickerAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.DamagedEvent; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 & L_J + */ +public final class VigorousCharge extends CardImpl { + + private static final String staticText = "Whenever that creature deals combat damage this turn, if this spell was kicked, you gain life equal to that damage"; + + public VigorousCharge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G}"); + + // Kicker {W} (You may pay an additional {W} as you cast this spell.) + this.addAbility(new KickerAbility("{W}")); + // Target creature gains trample until end of turn. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)); + // Whenever that creature deals combat damage this turn, if this spell was kicked, you gain life equal to that damage. + this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new GainAbilityTargetEffect(new VigorousChargeTriggeredAbility(), Duration.EndOfTurn), + new LockedInCondition(KickedCondition.instance), staticText)); + + } + + public VigorousCharge(final VigorousCharge card) { + super(card); + } + + @Override + public VigorousCharge copy() { + return new VigorousCharge(this); + } +} + +class VigorousChargeTriggeredAbility extends TriggeredAbilityImpl { + + public VigorousChargeTriggeredAbility() { + super(Zone.BATTLEFIELD, null); + } + + public VigorousChargeTriggeredAbility(final VigorousChargeTriggeredAbility ability) { + super(ability); + } + + @Override + public VigorousChargeTriggeredAbility copy() { + return new VigorousChargeTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.DAMAGED_CREATURE + || event.getType() == EventType.DAMAGED_PLAYER + || event.getType() == EventType.DAMAGED_PLANESWALKER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + DamagedEvent damageEvent = (DamagedEvent) event; + if (damageEvent.isCombatDamage()) { + if (event.getSourceId().equals(this.sourceId)) { + this.getEffects().clear(); + this.getEffects().add(new GainLifeEffect(damageEvent.getAmount())); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever {this} deals combat damage, you gain that much life."; + } +} diff --git a/Mage.Sets/src/mage/sets/Invasion.java b/Mage.Sets/src/mage/sets/Invasion.java index 7aef568c5a..beb5c28697 100644 --- a/Mage.Sets/src/mage/sets/Invasion.java +++ b/Mage.Sets/src/mage/sets/Invasion.java @@ -55,6 +55,7 @@ public final class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Benalish Heralds", 6, Rarity.UNCOMMON, mage.cards.b.BenalishHeralds.class)); cards.add(new SetCardInfo("Benalish Lancer", 7, Rarity.COMMON, mage.cards.b.BenalishLancer.class)); cards.add(new SetCardInfo("Benalish Trapper", 8, Rarity.COMMON, mage.cards.b.BenalishTrapper.class)); + cards.add(new SetCardInfo("Bend or Break", 137, Rarity.RARE, mage.cards.b.BendOrBreak.class)); cards.add(new SetCardInfo("Bind", 182, Rarity.RARE, mage.cards.b.Bind.class)); cards.add(new SetCardInfo("Blazing Specter", 236, Rarity.RARE, mage.cards.b.BlazingSpecter.class)); cards.add(new SetCardInfo("Blinding Light", 9, Rarity.UNCOMMON, mage.cards.b.BlindingLight.class)); @@ -88,6 +89,7 @@ public final class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Darigaaz's Attendant", 301, Rarity.UNCOMMON, mage.cards.d.DarigaazsAttendant.class)); cards.add(new SetCardInfo("Darigaaz, the Igniter", 243, Rarity.RARE, mage.cards.d.DarigaazTheIgniter.class)); cards.add(new SetCardInfo("Defiling Tears", 99, Rarity.UNCOMMON, mage.cards.d.DefilingTears.class)); + cards.add(new SetCardInfo("Death or Glory", 13, Rarity.RARE, mage.cards.d.DeathOrGlory.class)); cards.add(new SetCardInfo("Desperate Research", 100, Rarity.RARE, mage.cards.d.DesperateResearch.class)); cards.add(new SetCardInfo("Devouring Strossus", 101, Rarity.RARE, mage.cards.d.DevouringStrossus.class)); cards.add(new SetCardInfo("Dismantling Blow", 14, Rarity.COMMON, mage.cards.d.DismantlingBlow.class)); @@ -113,6 +115,7 @@ public final class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Fact or Fiction", 57, Rarity.UNCOMMON, mage.cards.f.FactOrFiction.class)); cards.add(new SetCardInfo("Faerie Squadron", 58, Rarity.COMMON, mage.cards.f.FaerieSquadron.class)); cards.add(new SetCardInfo("Fertile Ground", 188, Rarity.COMMON, mage.cards.f.FertileGround.class)); + cards.add(new SetCardInfo("Fight or Flight", 16, Rarity.RARE, mage.cards.f.FightOrFlight.class)); cards.add(new SetCardInfo("Firebrand Ranger", 143, Rarity.UNCOMMON, mage.cards.f.FirebrandRanger.class)); cards.add(new SetCardInfo("Firescreamer", 106, Rarity.COMMON, mage.cards.f.Firescreamer.class)); cards.add(new SetCardInfo("Fires of Yavimaya", 246, Rarity.UNCOMMON, mage.cards.f.FiresOfYavimaya.class)); @@ -217,6 +220,7 @@ public final class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Prohibit", 67, Rarity.COMMON, mage.cards.p.Prohibit.class)); cards.add(new SetCardInfo("Protective Sphere", 26, Rarity.COMMON, mage.cards.p.ProtectiveSphere.class)); cards.add(new SetCardInfo("Psychic Battle", 68, Rarity.RARE, mage.cards.p.PsychicBattle.class)); + cards.add(new SetCardInfo("Pulse of Llanowar", 202, Rarity.UNCOMMON, mage.cards.p.PulseOfLlanowar.class)); cards.add(new SetCardInfo("Pure Reflection", 27, Rarity.RARE, mage.cards.p.PureReflection.class)); cards.add(new SetCardInfo("Pyre Zombie", 261, Rarity.RARE, mage.cards.p.PyreZombie.class)); cards.add(new SetCardInfo("Quirion Elves", 203, Rarity.COMMON, mage.cards.q.QuirionElves.class)); @@ -250,6 +254,7 @@ public final class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Sabertooth Nishoba", 268, Rarity.RARE, mage.cards.s.SabertoothNishoba.class)); cards.add(new SetCardInfo("Salt Marsh", 326, Rarity.UNCOMMON, mage.cards.s.SaltMarsh.class)); cards.add(new SetCardInfo("Samite Archer", 269, Rarity.UNCOMMON, mage.cards.s.SamiteArcher.class)); + cards.add(new SetCardInfo("Samite Ministration", 36, Rarity.UNCOMMON, mage.cards.s.SamiteMinistration.class)); cards.add(new SetCardInfo("Sapphire Leech", 71, Rarity.RARE, mage.cards.s.SapphireLeech.class)); cards.add(new SetCardInfo("Saproling Infestation", 208, Rarity.RARE, mage.cards.s.SaprolingInfestation.class)); cards.add(new SetCardInfo("Saproling Symbiosis", 209, Rarity.RARE, mage.cards.s.SaprolingSymbiosis.class)); @@ -286,6 +291,7 @@ public final class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Spreading Plague", 125, Rarity.RARE, mage.cards.s.SpreadingPlague.class)); cards.add(new SetCardInfo("Stalking Assassin", 277, Rarity.RARE, mage.cards.s.StalkingAssassin.class)); cards.add(new SetCardInfo("Stand // Deliver", 292, Rarity.UNCOMMON, mage.cards.s.StandDeliver.class)); + cards.add(new SetCardInfo("Stand or Fall", 171, Rarity.RARE, mage.cards.s.StandOrFall.class)); cards.add(new SetCardInfo("Sterling Grove", 278, Rarity.UNCOMMON, mage.cards.s.SterlingGrove.class)); cards.add(new SetCardInfo("Stormscape Apprentice", 75, Rarity.COMMON, mage.cards.s.StormscapeApprentice.class)); cards.add(new SetCardInfo("Stormscape Master", 76, Rarity.RARE, mage.cards.s.StormscapeMaster.class)); @@ -346,6 +352,7 @@ public final class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Verduran Emissary", 221, Rarity.UNCOMMON, mage.cards.v.VerduranEmissary.class)); cards.add(new SetCardInfo("Viashino Grappler", 179, Rarity.COMMON, mage.cards.v.ViashinoGrappler.class)); cards.add(new SetCardInfo("Vicious Kavu", 284, Rarity.UNCOMMON, mage.cards.v.ViciousKavu.class)); + cards.add(new SetCardInfo("Vigorous Charge", 222, Rarity.COMMON, mage.cards.v.VigorousCharge.class)); cards.add(new SetCardInfo("Vile Consumption", 285, Rarity.RARE, mage.cards.v.VileConsumption.class)); cards.add(new SetCardInfo("Vodalian Hypnotist", 84, Rarity.UNCOMMON, mage.cards.v.VodalianHypnotist.class)); cards.add(new SetCardInfo("Vodalian Merchant", 85, Rarity.COMMON, mage.cards.v.VodalianMerchant.class)); From 9423731e97a156f7a603b126c4f55219ed1e0164 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 14 Oct 2018 10:14:36 +0200 Subject: [PATCH 070/167] * Fixed a problem with removing too much counters (caused by AI simulation). --- .../mage/cards/a/ArixmethesSlumberingIsle.java | 3 --- Mage.Sets/src/mage/cards/p/PredatoryFocus.java | 15 +++++---------- .../src/main/java/mage/abilities/AbilityImpl.java | 4 ++-- .../common/counter/RemoveCounterSourceEffect.java | 1 - 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/ArixmethesSlumberingIsle.java b/Mage.Sets/src/mage/cards/a/ArixmethesSlumberingIsle.java index 3c6578b392..615f5d7e24 100644 --- a/Mage.Sets/src/mage/cards/a/ArixmethesSlumberingIsle.java +++ b/Mage.Sets/src/mage/cards/a/ArixmethesSlumberingIsle.java @@ -28,7 +28,6 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.counters.CounterType; -import mage.filter.FilterSpell; import mage.game.Game; import mage.game.permanent.Permanent; @@ -38,8 +37,6 @@ import mage.game.permanent.Permanent; */ public final class ArixmethesSlumberingIsle extends CardImpl { - private static final FilterSpell filter = new FilterSpell("a spell"); - public ArixmethesSlumberingIsle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); diff --git a/Mage.Sets/src/mage/cards/p/PredatoryFocus.java b/Mage.Sets/src/mage/cards/p/PredatoryFocus.java index 807f524959..46311e34e0 100644 --- a/Mage.Sets/src/mage/cards/p/PredatoryFocus.java +++ b/Mage.Sets/src/mage/cards/p/PredatoryFocus.java @@ -1,12 +1,8 @@ package mage.cards.p; import java.util.UUID; - -import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.AsThoughEffect; import mage.abilities.effects.AsThoughEffectImpl; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AsThoughEffectType; @@ -24,7 +20,6 @@ public final class PredatoryFocus extends CardImpl { public PredatoryFocus(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}{G}"); - // You may have creatures you control assign their combat damage this turn as though they weren't blocked. this.getSpellAbility().addEffect(new PredatoryFocusEffect()); @@ -58,10 +53,10 @@ class PredatoryFocusEffect extends AsThoughEffectImpl { super.init(source, game); Player controller = game.getPlayer(source.getControllerId()); String sourceName = source.getSourceObject(game).getLogName(); - choseUse = controller.chooseUse(Outcome.Damage, "Have creatures you control deal combat damage this turn" + - " as though they weren't blocked?", source, game); - game.informPlayers(choseUse ? controller.getName()+" chose to use "+sourceName+"'s effect" : - controller.getName()+" chose not to use "+sourceName+"'s effect."); + choseUse = controller.chooseUse(Outcome.Damage, "Have creatures you control deal combat damage this turn" + + " as though they weren't blocked?", source, game); + game.informPlayers(choseUse ? controller.getName() + " chose to use " + sourceName + "'s effect" + : controller.getName() + " chose not to use " + sourceName + "'s effect."); } @Override @@ -78,4 +73,4 @@ class PredatoryFocusEffect extends AsThoughEffectImpl { public PredatoryFocusEffect copy() { return new PredatoryFocusEffect(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 6047e07969..7404a42527 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -15,8 +15,8 @@ import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.mana.DynamicManaEffect; import mage.abilities.effects.common.ManaEffect; +import mage.abilities.effects.mana.DynamicManaEffect; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.cards.Card; import mage.cards.SplitCard; @@ -116,7 +116,7 @@ public abstract class AbilityImpl implements Ability { this.costModificationActive = ability.costModificationActive; this.worksFaceDown = ability.worksFaceDown; this.abilityWord = ability.abilityWord; - this.sourceObject = ability.sourceObject; + this.sourceObject = null; // you may not copy this because otherwise simulation may modify real game object this.sourceObjectZoneChangeCounter = ability.sourceObjectZoneChangeCounter; this.canFizzle = ability.canFizzle; this.targetAdjuster = ability.targetAdjuster; diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCounterSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCounterSourceEffect.java index 4cd077f158..6345058e2f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCounterSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCounterSourceEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common.counter; import mage.abilities.Ability; From 01dfede9e918d721c00674cac3ead593bf16f4ae Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 20 Oct 2018 20:13:26 -0400 Subject: [PATCH 071/167] fixed Chance for Glory giving indestructible to noncreature permanents --- Mage.Sets/src/mage/cards/c/ChanceForGlory.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ChanceForGlory.java b/Mage.Sets/src/mage/cards/c/ChanceForGlory.java index ab8c37fb8a..dff4e834e2 100644 --- a/Mage.Sets/src/mage/cards/c/ChanceForGlory.java +++ b/Mage.Sets/src/mage/cards/c/ChanceForGlory.java @@ -1,16 +1,17 @@ package mage.cards.c; -import java.util.UUID; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.filter.StaticFilters; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class ChanceForGlory extends CardImpl { @@ -19,9 +20,10 @@ public final class ChanceForGlory extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{W}"); // Creatures you control gain indestructible. Take an extra turn after this one. At the beginning of that turn's end step, you lose the game. - this.getSpellAbility().addEffect(new GainAbilityControlledEffect( - IndestructibleAbility.getInstance(), Duration.EndOfGame - ).setText("Creatures you control gain indestructible")); + this.getSpellAbility().addEffect(new GainAbilityAllEffect( + IndestructibleAbility.getInstance(), Duration.EndOfGame, + StaticFilters.FILTER_CONTROLLED_CREATURES + ).setText("Creatures you control gain indestructible.")); this.getSpellAbility().addEffect(new AddExtraTurnControllerEffect(true)); } From b2beefc6807bc16d9fabc997862c04ee568e3387 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 20 Oct 2018 20:21:54 -0400 Subject: [PATCH 072/167] fixed Vraska, Golgari Queen's emblem not triggering --- ...alsDamageToAPlayerAllTriggeredAbility.java | 43 ++++++++++--------- .../emblems/VraskaGolgariQueenEmblem.java | 6 +-- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/common/DealsDamageToAPlayerAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsDamageToAPlayerAllTriggeredAbility.java index 0b0a41eaa6..4c662d195c 100644 --- a/Mage/src/main/java/mage/abilities/common/DealsDamageToAPlayerAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealsDamageToAPlayerAllTriggeredAbility.java @@ -13,7 +13,6 @@ import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** - * * @author LevelX2 */ public class DealsDamageToAPlayerAllTriggeredAbility extends TriggeredAbilityImpl { @@ -28,7 +27,11 @@ public class DealsDamageToAPlayerAllTriggeredAbility extends TriggeredAbilityImp } public DealsDamageToAPlayerAllTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional, SetTargetPointer setTargetPointer, boolean onlyCombat, boolean affectsDefendingPlayer) { - super(Zone.BATTLEFIELD, effect, optional); + this(Zone.BATTLEFIELD, effect, filter, optional, setTargetPointer, onlyCombat, affectsDefendingPlayer); + } + + public DealsDamageToAPlayerAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, SetTargetPointer setTargetPointer, boolean onlyCombat, boolean affectsDefendingPlayer) { + super(zone, effect, optional); this.setTargetPointer = setTargetPointer; this.filter = filter; this.onlyCombat = onlyCombat; @@ -57,27 +60,25 @@ public class DealsDamageToAPlayerAllTriggeredAbility extends TriggeredAbilityImp public boolean checkTrigger(GameEvent event, Game game) { if (!onlyCombat || ((DamagedPlayerEvent) event).isCombatDamage()) { Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null) { - if (filter.match(permanent, getSourceId(), getControllerId(), game)) { - for (Effect effect : this.getEffects()) { - effect.setValue("damage", event.getAmount()); - effect.setValue("sourceId", event.getSourceId()); - if (affectsDefendingPlayer) { - effect.setTargetPointer(new FixedTarget(event.getTargetId())); - continue; - } - switch (setTargetPointer) { - case PLAYER: - effect.setTargetPointer(new FixedTarget(permanent.getControllerId())); - break; - case PERMANENT: - effect.setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game))); - break; - } - + if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) { + for (Effect effect : this.getEffects()) { + effect.setValue("damage", event.getAmount()); + effect.setValue("sourceId", event.getSourceId()); + if (affectsDefendingPlayer) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + continue; } - return true; + switch (setTargetPointer) { + case PLAYER: + effect.setTargetPointer(new FixedTarget(permanent.getControllerId())); + break; + case PERMANENT: + effect.setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game))); + break; + } + } + return true; } } return false; diff --git a/Mage/src/main/java/mage/game/command/emblems/VraskaGolgariQueenEmblem.java b/Mage/src/main/java/mage/game/command/emblems/VraskaGolgariQueenEmblem.java index f7c2fac333..018943ecab 100644 --- a/Mage/src/main/java/mage/game/command/emblems/VraskaGolgariQueenEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/VraskaGolgariQueenEmblem.java @@ -3,11 +3,11 @@ package mage.game.command.emblems; import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility; import mage.abilities.effects.common.LoseGameTargetPlayerEffect; import mage.constants.SetTargetPointer; +import mage.constants.Zone; import mage.filter.StaticFilters; import mage.game.command.Emblem; /** - * * @author TheElk801 */ public final class VraskaGolgariQueenEmblem extends Emblem { @@ -17,9 +17,9 @@ public final class VraskaGolgariQueenEmblem extends Emblem { this.setName("Emblem Vraska"); this.setExpansionSetCodeForImage("GRN"); this.getAbilities().add(new DealsDamageToAPlayerAllTriggeredAbility( - new LoseGameTargetPlayerEffect(), + Zone.COMMAND, new LoseGameTargetPlayerEffect(), StaticFilters.FILTER_CONTROLLED_A_CREATURE, - false, SetTargetPointer.PLAYER, true + false, SetTargetPointer.NONE, true, true )); } } From 5a08632d59aa72f61f464c71528d200840b90eca Mon Sep 17 00:00:00 2001 From: L_J Date: Sun, 21 Oct 2018 16:59:10 +0200 Subject: [PATCH 073/167] Implemented Bands With Other --- .../mage/cards/a/AdventurersGuildhouse.java | 47 ++++++ .../src/mage/cards/c/CathedralOfSerra.java | 47 ++++++ .../src/mage/cards/m/MasterOfTheHunt.java | 40 +++++ .../src/mage/cards/m/MountainStronghold.java | 47 ++++++ Mage.Sets/src/mage/cards/o/OldFogey.java | 75 +++++++++ Mage.Sets/src/mage/cards/s/SeafarersQuay.java | 47 ++++++ .../src/mage/cards/s/ShelkinBrownie.java | 45 ++++++ Mage.Sets/src/mage/cards/t/Tolaria.java | 52 ++++++ Mage.Sets/src/mage/cards/u/UnholyCitadel.java | 47 ++++++ Mage.Sets/src/mage/sets/Unhinged.java | 1 + .../keyword/BandsWithOtherAbility.java | 79 +++++++++ .../main/java/mage/game/combat/Combat.java | 153 +++++++++++++----- .../java/mage/game/combat/CombatGroup.java | 58 +++++++ .../permanent/token/WolvesOfTheHuntToken.java | 32 ++++ 14 files changed, 727 insertions(+), 43 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AdventurersGuildhouse.java create mode 100644 Mage.Sets/src/mage/cards/c/CathedralOfSerra.java create mode 100644 Mage.Sets/src/mage/cards/m/MasterOfTheHunt.java create mode 100644 Mage.Sets/src/mage/cards/m/MountainStronghold.java create mode 100644 Mage.Sets/src/mage/cards/o/OldFogey.java create mode 100644 Mage.Sets/src/mage/cards/s/SeafarersQuay.java create mode 100644 Mage.Sets/src/mage/cards/s/ShelkinBrownie.java create mode 100644 Mage.Sets/src/mage/cards/t/Tolaria.java create mode 100644 Mage.Sets/src/mage/cards/u/UnholyCitadel.java create mode 100644 Mage/src/main/java/mage/abilities/keyword/BandsWithOtherAbility.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/WolvesOfTheHuntToken.java diff --git a/Mage.Sets/src/mage/cards/a/AdventurersGuildhouse.java b/Mage.Sets/src/mage/cards/a/AdventurersGuildhouse.java new file mode 100644 index 0000000000..f52a02aa30 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AdventurersGuildhouse.java @@ -0,0 +1,47 @@ + +package mage.cards.a; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.BandsWithOtherAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; + +/** + * + * @author L_J + */ +public final class AdventurersGuildhouse extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Green legendary creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.GREEN)); + filter.add(new SupertypePredicate(SuperType.LEGENDARY)); + } + + public AdventurersGuildhouse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // Green legendary creatures you control have "bands with other legendary creatures." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new BandsWithOtherAbility(SuperType.LEGENDARY), Duration.WhileOnBattlefield, filter))); + } + + public AdventurersGuildhouse(final AdventurersGuildhouse card) { + super(card); + } + + @Override + public AdventurersGuildhouse copy() { + return new AdventurersGuildhouse(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CathedralOfSerra.java b/Mage.Sets/src/mage/cards/c/CathedralOfSerra.java new file mode 100644 index 0000000000..b570289989 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CathedralOfSerra.java @@ -0,0 +1,47 @@ + +package mage.cards.c; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.BandsWithOtherAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; + +/** + * + * @author L_J + */ +public final class CathedralOfSerra extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("White legendary creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.WHITE)); + filter.add(new SupertypePredicate(SuperType.LEGENDARY)); + } + + public CathedralOfSerra(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // White legendary creatures you control have "bands with other legendary creatures." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new BandsWithOtherAbility(SuperType.LEGENDARY), Duration.WhileOnBattlefield, filter))); + } + + public CathedralOfSerra(final CathedralOfSerra card) { + super(card); + } + + @Override + public CathedralOfSerra copy() { + return new CathedralOfSerra(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MasterOfTheHunt.java b/Mage.Sets/src/mage/cards/m/MasterOfTheHunt.java new file mode 100644 index 0000000000..32ea8a44b5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MasterOfTheHunt.java @@ -0,0 +1,40 @@ + +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.permanent.token.WolvesOfTheHuntToken; + +/** + * @author L_J + */ +public final class MasterOfTheHunt extends CardImpl { + + public MasterOfTheHunt(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + this.subtype.add(SubType.HUMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Create a 1/1 green Wolf creature token named Wolves of the Hunt. It has “bands with other creatures named Wolves of the Hunt.” + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new WolvesOfTheHuntToken()), new ManaCostsImpl("{2}{G}{G}"))); + } + + public MasterOfTheHunt(final MasterOfTheHunt card) { + super(card); + } + + @Override + public MasterOfTheHunt copy() { + return new MasterOfTheHunt(this); + } + +} diff --git a/Mage.Sets/src/mage/cards/m/MountainStronghold.java b/Mage.Sets/src/mage/cards/m/MountainStronghold.java new file mode 100644 index 0000000000..64775cba11 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MountainStronghold.java @@ -0,0 +1,47 @@ + +package mage.cards.m; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.BandsWithOtherAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; + +/** + * + * @author L_J + */ +public final class MountainStronghold extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Red legendary creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + filter.add(new SupertypePredicate(SuperType.LEGENDARY)); + } + + public MountainStronghold(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // Red legendary creatures you control have "bands with other legendary creatures." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new BandsWithOtherAbility(SuperType.LEGENDARY), Duration.WhileOnBattlefield, filter))); + } + + public MountainStronghold(final MountainStronghold card) { + super(card); + } + + @Override + public MountainStronghold copy() { + return new MountainStronghold(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OldFogey.java b/Mage.Sets/src/mage/cards/o/OldFogey.java new file mode 100644 index 0000000000..4dd4ed481a --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OldFogey.java @@ -0,0 +1,75 @@ + +package mage.cards.o; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.BandsWithOtherAbility; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.abilities.keyword.EchoAbility; +import mage.abilities.keyword.FadingAbility; +import mage.abilities.keyword.FlankingAbility; +import mage.abilities.keyword.LandwalkAbility; +import mage.abilities.keyword.PhasingAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.abilities.keyword.RampageAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterCard; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; + +/** + * + * @author L_J + */ +public final class OldFogey extends CardImpl { + + private static final FilterCard filter = new FilterCard("Homarids"); + private static final FilterLandPermanent filter2 = new FilterLandPermanent("snow-covered plains"); + + static { + filter.add(new SubtypePredicate(SubType.HOMARID)); + filter2.add(new SupertypePredicate(SuperType.SNOW)); + filter2.add(new SubtypePredicate(SubType.PLAINS)); + } + + public OldFogey(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}{G}"); + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // Phasing + this.addAbility(PhasingAbility.getInstance()); + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + // Echo {G}{G} + this.addAbility(new EchoAbility("{G}{G}")); + // Fading 3 + this.addAbility(new FadingAbility(3, this)); + // Bands with other Dinosaurs + this.addAbility(new BandsWithOtherAbility(SubType.DINOSAUR)); + // Protection from Homarids + this.addAbility(new ProtectionAbility(filter)); + // Snow-covered plainswalk + this.addAbility(new LandwalkAbility(filter2)); + // Flanking + this.addAbility(new FlankingAbility()); + // Rampage 2 + this.addAbility(new RampageAbility(2)); + } + + public OldFogey(final OldFogey card) { + super(card); + } + + @Override + public OldFogey copy() { + return new OldFogey(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SeafarersQuay.java b/Mage.Sets/src/mage/cards/s/SeafarersQuay.java new file mode 100644 index 0000000000..ce62ca0040 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SeafarersQuay.java @@ -0,0 +1,47 @@ + +package mage.cards.s; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.BandsWithOtherAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; + +/** + * + * @author L_J + */ +public final class SeafarersQuay extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Blue legendary creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLUE)); + filter.add(new SupertypePredicate(SuperType.LEGENDARY)); + } + + public SeafarersQuay(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // Blue legendary creatures you control have "bands with other legendary creatures." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new BandsWithOtherAbility(SuperType.LEGENDARY), Duration.WhileOnBattlefield, filter))); + } + + public SeafarersQuay(final SeafarersQuay card) { + super(card); + } + + @Override + public SeafarersQuay copy() { + return new SeafarersQuay(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ShelkinBrownie.java b/Mage.Sets/src/mage/cards/s/ShelkinBrownie.java new file mode 100644 index 0000000000..0d5f206ecf --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShelkinBrownie.java @@ -0,0 +1,45 @@ + +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.LoseAbilityTargetEffect; +import mage.abilities.keyword.BandsWithOtherAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public final class ShelkinBrownie extends CardImpl { + + public ShelkinBrownie(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + this.subtype.add(SubType.OUPHE); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {T}: Target creature loses all "bands with other" abilities until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseAbilityTargetEffect(new BandsWithOtherAbility(), Duration.EndOfTurn), new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public ShelkinBrownie(final ShelkinBrownie card) { + super(card); + } + + @Override + public ShelkinBrownie copy() { + return new ShelkinBrownie(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/Tolaria.java b/Mage.Sets/src/mage/cards/t/Tolaria.java new file mode 100644 index 0000000000..24543958ca --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/Tolaria.java @@ -0,0 +1,52 @@ + +package mage.cards.t; + +import java.util.UUID; +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.condition.common.IsStepCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.common.continuous.LoseAbilityTargetEffect; +import mage.abilities.keyword.BandingAbility; +import mage.abilities.keyword.BandsWithOtherAbility; +import mage.abilities.mana.BlueManaAbility; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public final class Tolaria extends CardImpl { + + public Tolaria(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + this.addSuperType(SuperType.LEGENDARY); + + // {T}: Add {U}. + this.addAbility(new BlueManaAbility()); + + // {T}: Target creature loses banding and all "bands with other" abilities until end of turn. Activate this ability only during any upkeep step. + ActivatedAbilityImpl ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, + new LoseAbilityTargetEffect(BandingAbility.getInstance(), Duration.EndOfTurn), new TapSourceCost(), new IsStepCondition(PhaseStep.UPKEEP, false), + "{T}: Target creature loses banding and all \"bands with other\" abilities until end of turn. Activate this ability only during any upkeep step."); + ability.addEffect(new LoseAbilityTargetEffect(new BandsWithOtherAbility(), Duration.EndOfTurn)); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public Tolaria(final Tolaria card) { + super(card); + } + + @Override + public Tolaria copy() { + return new Tolaria(this); + } +} diff --git a/Mage.Sets/src/mage/cards/u/UnholyCitadel.java b/Mage.Sets/src/mage/cards/u/UnholyCitadel.java new file mode 100644 index 0000000000..7153b14a32 --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnholyCitadel.java @@ -0,0 +1,47 @@ + +package mage.cards.u; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.BandsWithOtherAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; + +/** + * + * @author L_J + */ +public final class UnholyCitadel extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Black legendary creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + filter.add(new SupertypePredicate(SuperType.LEGENDARY)); + } + + public UnholyCitadel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // Black legendary creatures you control have "bands with other legendary creatures." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new BandsWithOtherAbility(SuperType.LEGENDARY), Duration.WhileOnBattlefield, filter))); + } + + public UnholyCitadel(final UnholyCitadel card) { + super(card); + } + + @Override + public UnholyCitadel copy() { + return new UnholyCitadel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Unhinged.java b/Mage.Sets/src/mage/sets/Unhinged.java index 9a927bad34..bc8b373053 100644 --- a/Mage.Sets/src/mage/sets/Unhinged.java +++ b/Mage.Sets/src/mage/sets/Unhinged.java @@ -39,6 +39,7 @@ public final class Unhinged extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 139, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.UNH_FULL_ART_BASIC, false))); cards.add(new SetCardInfo("Mox Lotus", 124, Rarity.RARE, mage.cards.m.MoxLotus.class)); cards.add(new SetCardInfo("Now I Know My ABC's", 41, Rarity.RARE, mage.cards.n.NowIKnowMyABCs.class)); + cards.add(new SetCardInfo("Old Fogey", 106, Rarity.RARE, mage.cards.o.OldFogey.class)); cards.add(new SetCardInfo("Plains", 136, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.UNH_FULL_ART_BASIC, false))); cards.add(new SetCardInfo("Rare-B-Gone", 119, Rarity.RARE, mage.cards.r.RareBGone.class)); cards.add(new SetCardInfo("Six-y Beast", 89, Rarity.UNCOMMON, mage.cards.s.SixyBeast.class)); diff --git a/Mage/src/main/java/mage/abilities/keyword/BandsWithOtherAbility.java b/Mage/src/main/java/mage/abilities/keyword/BandsWithOtherAbility.java new file mode 100644 index 0000000000..528cc744df --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/BandsWithOtherAbility.java @@ -0,0 +1,79 @@ + +package mage.abilities.keyword; + +import mage.abilities.StaticAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; + +/** + * + * @author L_J + */ +public class BandsWithOtherAbility extends StaticAbility { + + private SubType subtype; + private SuperType supertype; + private String bandingName; + + public BandsWithOtherAbility() { + this(null, null, null); + } + + public BandsWithOtherAbility(SubType subtype) { + this(subtype, null, null); + } + + public BandsWithOtherAbility(SuperType supertype) { + this(null, supertype, null); + } + + public BandsWithOtherAbility(String bandingName) { + this(null, null, bandingName); + } + + public BandsWithOtherAbility(SubType subtype, SuperType supertype, String bandingName) { + super(Zone.ALL, null); + this.subtype = subtype; + this.supertype = supertype; + this.bandingName = bandingName; + } + + public BandsWithOtherAbility(BandsWithOtherAbility ability) { + super(ability); + this.subtype = ability.subtype; + this.supertype = ability.supertype; + this.bandingName = ability.bandingName; + } + + @Override + public BandsWithOtherAbility copy() { + return new BandsWithOtherAbility(this); + } + + public SubType getSubtype() { + return subtype; + } + + public SuperType getSupertype() { + return supertype; + } + + public String getName() { + return bandingName; + } + + @Override + public String getRule() { + StringBuilder sb = new StringBuilder("bands with other"); + if (subtype != null) { + return sb.append(' ').append(subtype.getDescription()).append('s').toString(); + } else if (supertype != null) { + return sb.append(' ').append(supertype.toString()).append(" creatures").toString(); + } else if (bandingName != null) { + return sb.append(" creatures named ").append(bandingName).toString(); + } + return "all \"" + sb.toString() + "\" abilities"; + } + +} diff --git a/Mage/src/main/java/mage/game/combat/Combat.java b/Mage/src/main/java/mage/game/combat/Combat.java index 5b56d49347..7a1c7a71d8 100644 --- a/Mage/src/main/java/mage/game/combat/Combat.java +++ b/Mage/src/main/java/mage/game/combat/Combat.java @@ -6,6 +6,7 @@ import mage.abilities.Ability; import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.RestrictionEffect; import mage.abilities.keyword.BandingAbility; +import mage.abilities.keyword.BandsWithOtherAbility; import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.special.JohanVigilanceAbility; import mage.constants.Outcome; @@ -14,8 +15,12 @@ import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreatureForCombatBlock; import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; import mage.filter.predicate.permanent.AttackingSameNotBandedPredicate; import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.game.Game; @@ -293,53 +298,115 @@ public class Combat implements Serializable, Copyable { Permanent attacker = game.getPermanent(creatureId); if (attacker != null && player != null) { CombatGroup combatGroup = findGroup(attacker.getId()); - if (combatGroup != null && attacker.getAbilities().containsKey(BandingAbility.getInstance().getId()) && attacker.getBandedCards().isEmpty() && getAttackers().size() > 1) { - boolean isBanded = false; - FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("attacking creature to band with " + attacker.getLogName()); - filter.add(Predicates.not(new PermanentIdPredicate(creatureId))); - filter.add(new AttackingSameNotBandedPredicate(combatGroup.getDefenderId())); // creature that isn't already banded, and is attacking the same player or planeswalker - while (player.canRespond()) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); - target.setRequired(false); - if (!target.canChoose(attackingPlayerId, game) - || game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, attackingPlayerId, attackingPlayerId)) - || !player.chooseUse(Outcome.Benefit, "Do you wish to " + (isBanded ? "band " + attacker.getLogName() + " with another " : "form a band with " + attacker.getLogName() + " and an ") + "attacking creature?", null, game)) { - break; - } - if (target.choose(Outcome.Benefit, attackingPlayerId, null, game)) { - isBanded = true; - for (UUID targetId : target.getTargets()) { - Permanent permanent = game.getPermanent(targetId); - if (permanent != null) { - - for (UUID bandedId : attacker.getBandedCards()) { - permanent.addBandedCard(bandedId); - Permanent banded = game.getPermanent(bandedId); - if (banded != null) { - banded.addBandedCard(targetId); - } - } - permanent.addBandedCard(creatureId); - attacker.addBandedCard(targetId); - if (!permanent.getAbilities().containsKey(BandingAbility.getInstance().getId())) { - filter.add(new AbilityPredicate(BandingAbility.class)); - } - } - - } + if (combatGroup != null && attacker.getBandedCards().isEmpty() && getAttackers().size() > 1) { + boolean canBand = attacker.getAbilities().containsKey(BandingAbility.getInstance().getId()); + List bandsWithOther = new ArrayList<>(); + for (Ability ability : attacker.getAbilities()) { + if (ability.getClass().equals(BandsWithOtherAbility.class)) { + bandsWithOther.add(ability); } } - if (isBanded) { - StringBuilder sb = new StringBuilder(player.getLogName()).append(" formed a band with ").append((attacker.getBandedCards().size() + 1) + " creatures: "); - sb.append(attacker.getLogName()); - for (UUID id : attacker.getBandedCards()) { - sb.append(", "); - Permanent permanent = game.getPermanent(id); - if (permanent != null) { - sb.append(permanent.getLogName()); + boolean canBandWithOther = !bandsWithOther.isEmpty(); + if (canBand || canBandWithOther) { + boolean isBanded = false; + FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("attacking creature to band with " + attacker.getLogName()); + filter.add(Predicates.not(new PermanentIdPredicate(creatureId))); + filter.add(new AttackingSameNotBandedPredicate(combatGroup.getDefenderId())); // creature that isn't already banded, and is attacking the same player or planeswalker + List> predicates = new ArrayList<>(); + if (!canBand && canBandWithOther) { + for (Ability ab : bandsWithOther) { + BandsWithOtherAbility ability = (BandsWithOtherAbility) ab; + if (ability.getSubtype() != null) { + predicates.add(new SubtypePredicate(ability.getSubtype())); + } + if (ability.getSupertype() != null) { + predicates.add(new SupertypePredicate(ability.getSupertype())); + } + if (ability.getName() != null) { + predicates.add(new NamePredicate(ability.getName())); + } + } + filter.add(Predicates.or(predicates)); + } + while (player.canRespond()) { + TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + target.setRequired(false); + canBand &= target.canChoose(attackingPlayerId, game); + canBandWithOther &= target.canChoose(attackingPlayerId, game); + if (game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, attackingPlayerId, attackingPlayerId)) + || (!canBand && !canBandWithOther) + || !player.chooseUse(Outcome.Benefit, "Do you wish to " + (isBanded ? "band " + attacker.getLogName() + " with another " : "form a band with " + attacker.getLogName() + " and an ") + "attacking creature?", null, game)) { + break; + } + + if (canBand && canBandWithOther) { + if (player.chooseUse(Outcome.Detriment, "Choose type of banding ability to apply:", attacker.getLogName(), "Banding", "Bands with other", null, game)) { + canBandWithOther = false; + } else { + canBand = false; + for (Ability ab : bandsWithOther) { + BandsWithOtherAbility ability = (BandsWithOtherAbility) ab; + if (ability.getSubtype() != null) { + predicates.add(new SubtypePredicate(ability.getSubtype())); + } + if (ability.getSupertype() != null) { + predicates.add(new SupertypePredicate(ability.getSupertype())); + } + if (ability.getName() != null) { + predicates.add(new NamePredicate(ability.getName())); + } + } + filter.add(Predicates.or(predicates)); + } + } + + if (target.choose(Outcome.Benefit, attackingPlayerId, null, game)) { + isBanded = true; + for (UUID targetId : target.getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null) { + + for (UUID bandedId : attacker.getBandedCards()) { + permanent.addBandedCard(bandedId); + Permanent banded = game.getPermanent(bandedId); + if (banded != null) { + banded.addBandedCard(targetId); + } + } + permanent.addBandedCard(creatureId); + attacker.addBandedCard(targetId); + if (canBand) { + if (!permanent.getAbilities().containsKey(BandingAbility.getInstance().getId())) { + filter.add(new AbilityPredicate(BandingAbility.class)); + canBandWithOther = false; + } + } else if (canBandWithOther) { + List> newPredicates = new ArrayList<>(); + for (Predicate predicate : predicates) { + if (predicate.apply(permanent, game)) { + newPredicates.add(predicate); + } + } + filter.add(Predicates.or(newPredicates)); + canBand = false; + } + } + + } } } - game.informPlayers(sb.toString()); + if (isBanded) { + StringBuilder sb = new StringBuilder(player.getLogName()).append(" formed a band with ").append((attacker.getBandedCards().size() + 1) + " creatures: "); + sb.append(attacker.getLogName()); + for (UUID id : attacker.getBandedCards()) { + sb.append(", "); + Permanent permanent = game.getPermanent(id); + if (permanent != null) { + sb.append(permanent.getLogName()); + } + } + game.informPlayers(sb.toString()); + } } } } diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index e357b6df97..be2f139af6 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -5,10 +5,12 @@ import java.io.Serializable; import java.util.*; import java.util.stream.Stream; +import mage.abilities.Ability; import mage.abilities.common.ControllerAssignCombatDamageToBlockersAbility; import mage.abilities.common.ControllerDivideCombatDamageAbility; import mage.abilities.common.DamageAsThoughNotBlockedAbility; import mage.abilities.keyword.BandingAbility; +import mage.abilities.keyword.BandsWithOtherAbility; import mage.abilities.keyword.CantBlockAloneAbility; import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.DoubleStrikeAbility; @@ -110,6 +112,56 @@ public class CombatGroup implements Serializable, Copyable { return perm.getAbilities().containsKey(BandingAbility.getInstance().getId()); } + private boolean appliesBandsWithOther(List creatureIds, Game game) { + for (UUID creatureId : creatureIds) { + Permanent perm = game.getPermanent(creatureId); + if (perm != null && perm.getBandedCards() != null) { + for (Ability ab : perm.getAbilities()) { + if (ab.getClass().equals(BandsWithOtherAbility.class)) { + BandsWithOtherAbility ability = (BandsWithOtherAbility) ab; + if (ability.getSubtype() != null) { + if (perm.hasSubtype(ability.getSubtype(), game)) { + for (UUID bandedId : creatureIds) { + if (!bandedId.equals(creatureId)) { + Permanent banded = game.getPermanent(bandedId); + if (banded != null && banded.hasSubtype(ability.getSubtype(), game)) { + return true; + } + } + } + } + } + if (ability.getSupertype() != null) { + if (perm.getSuperType().contains(ability.getSupertype())) { + for (UUID bandedId : creatureIds) { + if (!bandedId.equals(creatureId)) { + Permanent banded = game.getPermanent(bandedId); + if (banded != null && banded.getSuperType().contains(ability.getSupertype())) { + return true; + } + } + } + } + } + if (ability.getName() != null) { + if (perm.getName().equals(ability.getName())) { + for (UUID bandedId : creatureIds) { + if (!bandedId.equals(creatureId)) { + Permanent banded = game.getPermanent(bandedId); + if (banded != null && banded.getName().equals(ability.getName())) { + return true; + } + } + } + } + } + } + } + } + } + return false; + } + public void assignDamageToBlockers(boolean first, Game game) { if (!attackers.isEmpty() && (!first || hasFirstOrDoubleStrike(game))) { Permanent attacker = game.getPermanent(attackers.get(0)); @@ -837,6 +889,9 @@ public class CombatGroup implements Serializable, Copyable { } } } + if (appliesBandsWithOther(attackers, game)) { // 702.21k - both a [quality] creature with “bands with other [quality]” and another [quality] creature (...) + return true; + } return false; } @@ -855,6 +910,9 @@ public class CombatGroup implements Serializable, Copyable { } } } + if (appliesBandsWithOther(blockers, game)) { // 702.21j - both a [quality] creature with “bands with other [quality]” and another [quality] creature (...) + return true; + } for (Permanent defensiveFormation : game.getBattlefield().getAllActivePermanents(defendingPlayerId)) { if (defensiveFormation.getAbilities().containsKey(ControllerAssignCombatDamageToBlockersAbility.getInstance().getId())) { return true; diff --git a/Mage/src/main/java/mage/game/permanent/token/WolvesOfTheHuntToken.java b/Mage/src/main/java/mage/game/permanent/token/WolvesOfTheHuntToken.java new file mode 100644 index 0000000000..af156cd597 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/WolvesOfTheHuntToken.java @@ -0,0 +1,32 @@ + +package mage.game.permanent.token; + +import mage.constants.CardType; +import mage.constants.SubType; +import mage.MageInt; +import mage.abilities.keyword.BandsWithOtherAbility; + +/** + * + * @author L_J + */ +public final class WolvesOfTheHuntToken extends TokenImpl { + + public WolvesOfTheHuntToken() { + super("Wolves of the Hunt", "1/1 green Wolf creature token named Wolves of the Hunt"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.WOLF); + color.setGreen(true); + power = new MageInt(1); + toughness = new MageInt(1); + this.addAbility(new BandsWithOtherAbility("Wolves of the Hunt")); + } + + public WolvesOfTheHuntToken(final WolvesOfTheHuntToken token) { + super(token); + } + + public WolvesOfTheHuntToken copy() { + return new WolvesOfTheHuntToken(this); + } +} From e6b78d7a2ef417fcf49c56f739e9ad5a5a52cd1b Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 21 Oct 2018 21:36:53 +0200 Subject: [PATCH 074/167] Updated some libs to newer versions. --- Mage.Client/pom.xml | 10 +++++----- Mage.Server/pom.xml | 34 +++++++++++++++++----------------- Mage.Verify/pom.xml | 4 ++-- pom.xml | 2 +- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml index 7a5a733b2c..35baf24109 100644 --- a/Mage.Client/pom.xml +++ b/Mage.Client/pom.xml @@ -158,11 +158,11 @@ 1.7 - - org.ocpsoft.prettytime - prettytime - 3.2.7.Final - + + org.ocpsoft.prettytime + prettytime + 3.2.7.Final + diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml index ef2b5d1b81..91d840c5a8 100644 --- a/Mage.Server/pom.xml +++ b/Mage.Server/pom.xml @@ -22,8 +22,8 @@ org.apache.commons commons-lang3 - 3.3.2 - + 3.8.1 + ${project.groupId} mage-common @@ -76,16 +76,16 @@ ${project.version} runtime - + ${project.groupId} mage-game-brawlduel ${project.version} runtime - + org.apache.commons commons-compress - 1.16.1 + 1.18 @@ -194,58 +194,58 @@ org.apache.shiro shiro-core - 1.2.4 + 1.4.0 jar com.google.api-client google-api-client - 1.21.0 + 1.25.0 jar com.google.apis google-api-services-gmail - v1-rev35-1.21.0 + v1-rev82-1.23.0 jar com.google.oauth-client google-oauth-client-java6 - 1.19.0 + 1.25.0 jar com.google.oauth-client google-oauth-client-jetty - 1.19.0 + 1.25.0 jar javax.mail mail - 1.4.2 + 1.4.7 jar com.sun.jersey jersey-core - 1.19 + 1.19.4 com.sun.jersey jersey-client - 1.19 + 1.19.4 com.sun.jersey.contribs jersey-multipart - 1.19 + 1.19.4 org.xerial sqlite-jdbc - 3.7.2 + 3.25.2 @@ -254,7 +254,7 @@ org.jvnet.jaxb2.maven2 maven-jaxb2-plugin - 0.12.3 + 0.14.0 mage.server.util.config ./src/main/xml-resources/jaxb/Config/ @@ -320,7 +320,7 @@ - + mage-server diff --git a/Mage.Verify/pom.xml b/Mage.Verify/pom.xml index 90c41da866..cb1f3be867 100644 --- a/Mage.Verify/pom.xml +++ b/Mage.Verify/pom.xml @@ -32,7 +32,7 @@ com.fasterxml.jackson.core jackson-databind - 2.6.3 + 2.9.7 @@ -67,7 +67,7 @@ org.apache.maven.plugins maven-compiler-plugin - diff --git a/pom.xml b/pom.xml index 39d6abf21b..62c3c3a0d9 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ org.slf4j slf4j-log4j12 - 1.7.19 + 1.7.25 From 26a93d44271e6c7b59c04158fbd97e0f8f80ea56 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 21 Oct 2018 21:37:23 +0200 Subject: [PATCH 075/167] Reworked ability source object handling. --- Mage.Sets/src/mage/cards/c/CyclopeanTomb.java | 11 +- Mage.Sets/src/mage/cards/g/GiantOyster.java | 8 +- .../src/mage/cards/p/PermeatingMass.java | 7 +- .../oneshot/damage/SpitefulShadowsTest.java | 4 +- .../oneshot/exile/FiendHunterTest.java | 4 +- .../other/LimitedCountedActivationsTest.java | 359 +++++++++--------- .../mage/test/cards/mana/HarvestMageTest.java | 35 ++ .../test/multiplayer/BlatantThieveryTest.java | 1 + .../src/main/java/mage/abilities/Ability.java | 15 +- .../main/java/mage/abilities/AbilityImpl.java | 65 ++-- .../mage/abilities/TriggeredAbilityImpl.java | 4 - ...LeaveReturnExiledToBattlefieldAbility.java | 1 - .../effects/common/SacrificeSourceEffect.java | 9 +- .../abilities/meta/OrTriggeredAbility.java | 23 +- Mage/src/main/java/mage/game/GameImpl.java | 10 +- .../main/java/mage/game/command/Emblem.java | 1 - .../main/java/mage/game/command/Plane.java | 4 +- .../java/mage/game/stack/StackAbility.java | 9 +- .../main/java/mage/players/PlayerImpl.java | 10 +- 19 files changed, 292 insertions(+), 288 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvestMageTest.java diff --git a/Mage.Sets/src/mage/cards/c/CyclopeanTomb.java b/Mage.Sets/src/mage/cards/c/CyclopeanTomb.java index 77e7787f93..b37803bd25 100644 --- a/Mage.Sets/src/mage/cards/c/CyclopeanTomb.java +++ b/Mage.Sets/src/mage/cards/c/CyclopeanTomb.java @@ -1,6 +1,9 @@ - package mage.cards.c; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; @@ -31,11 +34,6 @@ import mage.target.common.TargetLandPermanent; import mage.target.targetpointer.FixedTarget; import mage.watchers.Watcher; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - /** * * @author MTGfan @@ -123,7 +121,6 @@ class CyclopeanTombCreateTriggeredEffect extends OneShotEffect { if (controller != null) { Permanent tomb = game.getPermanentOrLKIBattlefield(source.getSourceId()); // we need to set the correct source object DelayedTriggeredAbility ability = new AtTheBeginOfYourNextUpkeepDelayedTriggeredAbility(new CyclopeanTombEffect(), Duration.EndOfGame, false); - ability.setSourceObject(tomb, game); ability.setControllerId(source.getControllerId()); ability.setSourceId(source.getSourceId()); game.addDelayedTriggeredAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GiantOyster.java b/Mage.Sets/src/mage/cards/g/GiantOyster.java index 05617d00dc..53e103906b 100644 --- a/Mage.Sets/src/mage/cards/g/GiantOyster.java +++ b/Mage.Sets/src/mage/cards/g/GiantOyster.java @@ -1,5 +1,6 @@ package mage.cards.g; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; @@ -27,8 +28,6 @@ import mage.players.Player; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; -import java.util.UUID; - /** * * @author noahg @@ -43,7 +42,7 @@ public final class GiantOyster extends CardImpl { public GiantOyster(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); - + this.subtype.add(SubType.OYSTER); this.power = new MageInt(0); this.toughness = new MageInt(3); @@ -111,7 +110,6 @@ class GiantOysterCreateDelayedTriggerEffects extends OneShotEffect { Effect addCountersEffect = new AddCountersTargetEffect(CounterType.M1M1.createInstance(1)); addCountersEffect.setTargetPointer(getTargetPointer().getFixedTarget(game, source)); DelayedTriggeredAbility drawStepAbility = new AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(addCountersEffect, Duration.Custom, false); - drawStepAbility.setSourceObject(oyster, game); drawStepAbility.setControllerId(source.getControllerId()); UUID drawStepAbilityUUID = game.addDelayedTriggeredAbility(drawStepAbility, source); @@ -161,4 +159,4 @@ class GiantOysterLeaveUntapDelayedTriggeredAbility extends DelayedTriggeredAbili public String getRule() { return "When {this} leaves the battlefield or becomes untapped, remove all -1/-1 counters from the creature."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/p/PermeatingMass.java b/Mage.Sets/src/mage/cards/p/PermeatingMass.java index 58a7466de3..286739e23c 100644 --- a/Mage.Sets/src/mage/cards/p/PermeatingMass.java +++ b/Mage.Sets/src/mage/cards/p/PermeatingMass.java @@ -1,4 +1,3 @@ - package mage.cards.p; import java.util.UUID; @@ -9,9 +8,9 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.functions.EmptyApplyToPermanent; @@ -23,7 +22,7 @@ import mage.util.functions.EmptyApplyToPermanent; public final class PermeatingMass extends CardImpl { public PermeatingMass(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(1); this.toughness = new MageInt(3); @@ -62,7 +61,7 @@ class PermeatingMassEffect extends OneShotEffect { public boolean apply(Game game, Ability ability) { Permanent copyTo = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, ability)); if (copyTo != null) { - Permanent copyFrom = (Permanent) ability.getSourceObject(game); + Permanent copyFrom = ability.getSourcePermanentOrLKI(game); if (copyFrom != null) { game.copyPermanent(Duration.Custom, copyFrom, copyTo.getId(), ability, new EmptyApplyToPermanent()); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/SpitefulShadowsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/SpitefulShadowsTest.java index 42628bca6c..4eaffcbd2b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/SpitefulShadowsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/SpitefulShadowsTest.java @@ -39,9 +39,11 @@ public class SpitefulShadowsTest extends CardTestPlayerBase { @Test public void testCard1() { - addCard(Zone.BATTLEFIELD, playerA, "Craw Wurm"); + addCard(Zone.BATTLEFIELD, playerA, "Craw Wurm"); // Creature 6/4 addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + // Enchant creature + // Whenever enchanted creature is dealt damage, it deals that much damage to its controller. addCard(Zone.HAND, playerA, "Spiteful Shadows"); addCard(Zone.HAND, playerA, "Lightning Bolt"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/FiendHunterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/FiendHunterTest.java index 705a274c36..e7aa5a62bd 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/FiendHunterTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/exile/FiendHunterTest.java @@ -1,4 +1,3 @@ - package org.mage.test.cards.abilities.oneshot.exile; import mage.constants.PhaseStep; @@ -70,10 +69,9 @@ public class FiendHunterTest extends CardTestPlayerBase { execute(); assertExileCount("Silvercoat Lion", 1); - assertPermanentCount(playerB, "Primeval Titan", 1); - assertPermanentCount(playerA, "Fiend Hunter", 1); assertPermanentCount(playerA, "Restoration Angel", 1); + assertPermanentCount(playerB, "Primeval Titan", 1); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/LimitedCountedActivationsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/LimitedCountedActivationsTest.java index 7901a6d153..74b14b0b2f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/LimitedCountedActivationsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/LimitedCountedActivationsTest.java @@ -1,179 +1,180 @@ - -package org.mage.test.cards.abilities.other; - -import mage.constants.PhaseStep; -import mage.constants.Zone; -import org.junit.Test; -import org.mage.test.serverside.base.CardTestPlayerBase; - -/** - * - * @author LevelX2 - */ -public class LimitedCountedActivationsTest extends CardTestPlayerBase { - - /** - * Tests usage of ActivationInfo class - */ - @Test - public void testDragonWhelpActivatedThreeTimes() { - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); - // Flying - // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. - addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 - - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - - attack(1, playerA, "Dragon Whelp"); - - setStopAt(2, PhaseStep.UPKEEP); - execute(); - - assertPermanentCount(playerA, "Dragon Whelp", 1); - - assertLife(playerA, 20); - assertLife(playerB, 15); - } - - @Test - public void testDragonWhelpActivatedFourTimes() { - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); - // Flying - // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. - addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 - - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - - attack(1, playerA, "Dragon Whelp"); - - setStopAt(2, PhaseStep.UPKEEP); - execute(); - - assertPermanentCount(playerA, "Dragon Whelp", 0); - assertGraveyardCount(playerA, "Dragon Whelp", 1); - - assertLife(playerA, 20); - assertLife(playerB, 14); - } - - @Test - public void testDragonWhelpActivatedFiveTimes() { - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); - // Flying - // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. - addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 - - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); - - attack(1, playerA, "Dragon Whelp"); - - setStopAt(2, PhaseStep.UPKEEP); - execute(); - - assertPermanentCount(playerA, "Dragon Whelp", 0); - assertGraveyardCount(playerA, "Dragon Whelp", 1); - - assertLife(playerA, 20); - assertLife(playerB, 13); - } - - @Test - public void testDragonWhelpTwoObjects() { - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); - addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); - // Flying - // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. - addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 - // Put target creature card from a graveyard onto the battlefield under your control. You lose life equal to its converted mana cost. - addCard(Zone.HAND, playerA, "Reanimate", 1); - // Target creature gains haste until end of turn. - addCard(Zone.HAND, playerA, "Unnatural Speed", 1); - - addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); - // Destroy target nonartifact, nonblack creature. It can't be regenerated. - addCard(Zone.HAND, playerB, "Terror", 1); // {1}{B} - - activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Terror", "Dragon Whelp"); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate", "Dragon Whelp"); - castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Unnatural Speed", "Dragon Whelp"); - - activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); - activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); - activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); - - attack(1, playerA, "Dragon Whelp"); - - setStopAt(2, PhaseStep.UPKEEP); - execute(); - - assertGraveyardCount(playerA, "Unnatural Speed", 1); - assertGraveyardCount(playerA, "Reanimate", 1); - - assertGraveyardCount(playerB, "Terror", 1); - - assertPermanentCount(playerA, "Dragon Whelp", 1); - assertPowerToughness(playerA, "Dragon Whelp", 2, 3); - assertGraveyardCount(playerA, "Dragon Whelp", 0); - - assertLife(playerA, 16); - assertLife(playerB, 15); - } - - @Test - public void testDragonWhelpDontSacrificeNewObject() { - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 8); - addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); - // Flying - // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. - addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 - // Put target creature card from a graveyard onto the battlefield under your control. You lose life equal to its converted mana cost. - addCard(Zone.HAND, playerA, "Reanimate", 1); - // Target creature gains haste until end of turn. - addCard(Zone.HAND, playerA, "Unnatural Speed", 1); - - addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); - // Destroy target nonartifact, nonblack creature. It can't be regenerated. - addCard(Zone.HAND, playerB, "Terror", 1); // {1}{B} - - activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); - activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); - activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); - activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Terror", "Dragon Whelp"); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate", "Dragon Whelp"); - castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Unnatural Speed", "Dragon Whelp"); - - activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); - activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); - activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); - - attack(1, playerA, "Dragon Whelp"); - - setStopAt(2, PhaseStep.UPKEEP); - execute(); - - assertGraveyardCount(playerA, "Unnatural Speed", 1); - assertGraveyardCount(playerA, "Reanimate", 1); - - assertGraveyardCount(playerB, "Terror", 1); - - assertPermanentCount(playerA, "Dragon Whelp", 1); - assertPowerToughness(playerA, "Dragon Whelp", 2, 3); - assertGraveyardCount(playerA, "Dragon Whelp", 0); - - assertLife(playerA, 16); - assertLife(playerB, 15); - } -} +package org.mage.test.cards.abilities.other; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class LimitedCountedActivationsTest extends CardTestPlayerBase { + + /** + * Tests usage of ActivationInfo class + */ + @Test + public void testDragonWhelpActivatedThreeTimes() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); + // Flying + // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. + addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + + attack(1, playerA, "Dragon Whelp"); + + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertPermanentCount(playerA, "Dragon Whelp", 1); + + assertLife(playerA, 20); + assertLife(playerB, 15); + } + + @Test + public void testDragonWhelpActivatedFourTimes() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); + // Flying + // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. + addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + + attack(1, playerA, "Dragon Whelp"); + + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertPermanentCount(playerA, "Dragon Whelp", 0); + assertGraveyardCount(playerA, "Dragon Whelp", 1); + + assertLife(playerA, 20); + assertLife(playerB, 14); + } + + @Test + public void testDragonWhelpActivatedFiveTimes() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); + // Flying + // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. + addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: "); + + attack(1, playerA, "Dragon Whelp"); + + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertPermanentCount(playerA, "Dragon Whelp", 0); + assertGraveyardCount(playerA, "Dragon Whelp", 1); + + assertLife(playerA, 20); + assertLife(playerB, 13); + } + + @Test + public void testDragonWhelpTwoObjects() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + // Flying + // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. + addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 + // Put target creature card from a graveyard onto the battlefield under your control. You lose life equal to its converted mana cost. + addCard(Zone.HAND, playerA, "Reanimate", 1); + // Target creature gains haste until end of turn. + addCard(Zone.HAND, playerA, "Unnatural Speed", 1); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); + // Destroy target nonartifact, nonblack creature. It can't be regenerated. + addCard(Zone.HAND, playerB, "Terror", 1); // {1}{B} + + activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Terror", "Dragon Whelp"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate", "Dragon Whelp"); + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Unnatural Speed", "Dragon Whelp"); + + activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); + activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); + activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); + + attack(1, playerA, "Dragon Whelp"); + + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertGraveyardCount(playerA, "Unnatural Speed", 1); + assertGraveyardCount(playerA, "Reanimate", 1); + + assertGraveyardCount(playerB, "Terror", 1); + + assertPermanentCount(playerA, "Dragon Whelp", 1); + assertPowerToughness(playerA, "Dragon Whelp", 2, 3); + assertGraveyardCount(playerA, "Dragon Whelp", 0); + + assertLife(playerA, 16); + assertLife(playerB, 15); + } + + @Test + public void testDragonWhelpDontSacrificeNewObject() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 8); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + // Flying + // {R}: Dragon Whelp gets +1/+0 until end of turn. If this ability has been activated four or more times this turn, sacrifice Dragon Whelp at the beginning of the next end step. + addCard(Zone.BATTLEFIELD, playerA, "Dragon Whelp", 1); // 3/3 + // Put target creature card from a graveyard onto the battlefield under your control. You lose life equal to its converted mana cost. + addCard(Zone.HAND, playerA, "Reanimate", 1); + // Target creature gains haste until end of turn. + addCard(Zone.HAND, playerA, "Unnatural Speed", 1); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); + // Destroy target nonartifact, nonblack creature. It can't be regenerated. + addCard(Zone.HAND, playerB, "Terror", 1); // {1}{B} + + activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); + activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); + activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); + activateAbility(1, PhaseStep.UPKEEP, playerA, "{R}: "); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Terror", "Dragon Whelp"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate", "Dragon Whelp"); + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Unnatural Speed", "Dragon Whelp"); + + activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); + activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); + activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "{R}: "); + + attack(1, playerA, "Dragon Whelp"); + + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertGraveyardCount(playerA, "Unnatural Speed", 1); + assertGraveyardCount(playerA, "Reanimate", 1); + + assertGraveyardCount(playerB, "Terror", 1); + + assertLife(playerA, 16); + assertLife(playerB, 15); + + assertGraveyardCount(playerA, "Dragon Whelp", 0); + + assertPermanentCount(playerA, "Dragon Whelp", 1); + assertPowerToughness(playerA, "Dragon Whelp", 2, 3); + + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvestMageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvestMageTest.java new file mode 100644 index 0000000000..ac39080b79 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvestMageTest.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.mage.test.cards.mana; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class HarvestMageTest extends CardTestPlayerBase { + + @Test + public void testOneInstance() { + addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + + // {G}, {T}, Discard a card: Until end of turn, if you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount. + addCard(Zone.HAND, playerA, "Harvest Mage", 1); // Creature 1/1 {G} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Harvest Mage"); + + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{G}, {T}, Discard a card: Until end of turn"); + setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerA, "Harvest Mage", 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/multiplayer/BlatantThieveryTest.java b/Mage.Tests/src/test/java/org/mage/test/multiplayer/BlatantThieveryTest.java index a5447b94b1..049e958347 100644 --- a/Mage.Tests/src/test/java/org/mage/test/multiplayer/BlatantThieveryTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/multiplayer/BlatantThieveryTest.java @@ -52,6 +52,7 @@ public class BlatantThieveryTest extends CardTestMultiPlayerBase { setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertGraveyardCount(playerA, "Blatant Thievery", 1); assertPermanentCount(playerA, "Silvercoat Lion", 1); assertPermanentCount(playerA, "Walking Corpse", 1); assertPermanentCount(playerA, "Pillarfield Ox", 1); diff --git a/Mage/src/main/java/mage/abilities/Ability.java b/Mage/src/main/java/mage/abilities/Ability.java index 9701e1a140..4ef44edad6 100644 --- a/Mage/src/main/java/mage/abilities/Ability.java +++ b/Mage/src/main/java/mage/abilities/Ability.java @@ -479,16 +479,7 @@ public interface Ability extends Controllable, Serializable { boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game); /** - * Sets the object that actually existed while a ability triggerd or an - * ability was activated. - * - * @param mageObject - * @param game - */ - void setSourceObject(MageObject mageObject, Game game); - - /** - * Returns the object that actually existed while a ability triggerd or an + * Returns the object that actually existed while a ability triggered or an * ability was activated. If not set yet, the current object will be * retrieved from the game. * @@ -497,6 +488,8 @@ public interface Ability extends Controllable, Serializable { */ MageObject getSourceObject(Game game); + void setSourceObjectZoneChangeCounter(int zoneChangeCounter); + int getSourceObjectZoneChangeCounter(); /** @@ -520,6 +513,8 @@ public interface Ability extends Controllable, Serializable { */ Permanent getSourcePermanentIfItStillExists(Game game); + Permanent getSourcePermanentOrLKI(Game game); + String getTargetDescription(Targets targets, Game game); void setCanFizzle(boolean canFizzle); diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 7404a42527..481658c507 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -5,7 +5,6 @@ import java.util.Iterator; import java.util.List; import java.util.UUID; import mage.MageObject; -import mage.MageObjectReference; import mage.Mana; import mage.abilities.costs.*; import mage.abilities.costs.common.PayLifeCost; @@ -67,7 +66,6 @@ public abstract class AbilityImpl implements Ability { protected boolean costModificationActive = true; protected boolean activated = false; protected boolean worksFaceDown = false; - protected MageObject sourceObject; protected int sourceObjectZoneChangeCounter; protected List watchers = new ArrayList<>(); protected List subAbilities = null; @@ -116,7 +114,6 @@ public abstract class AbilityImpl implements Ability { this.costModificationActive = ability.costModificationActive; this.worksFaceDown = ability.worksFaceDown; this.abilityWord = ability.abilityWord; - this.sourceObject = null; // you may not copy this because otherwise simulation may modify real game object this.sourceObjectZoneChangeCounter = ability.sourceObjectZoneChangeCounter; this.canFizzle = ability.canFizzle; this.targetAdjuster = ability.targetAdjuster; @@ -131,8 +128,6 @@ public abstract class AbilityImpl implements Ability { public void newId() { if (!(this instanceof MageSingleton)) { this.id = UUID.randomUUID(); -// this.sourceObject = null; -// this.sourceObjectZoneChangeCounter = -1; } getEffects().newId(); } @@ -226,8 +221,10 @@ public abstract class AbilityImpl implements Ability { return false; } - getSourceObject(game); - + MageObject sourceObject = getSourceObject(game); + if (getSourceObjectZoneChangeCounter() == 0) { + setSourceObjectZoneChangeCounter(game.getState().getZoneChangeCounter(getSourceId())); + } if (controller.isTestMode()) { if (!controller.addTargets(this, game)) { return false; @@ -1160,58 +1157,44 @@ public abstract class AbilityImpl implements Ability { @Override public MageObject getSourceObject(Game game) { - if (sourceObject == null) { - setSourceObject(null, game); - if (sourceObject == null) { - logger.warn("Source object could not be retrieved: " + this.getRule()); - } - } - return sourceObject; + return game.getObject(getSourceId()); } @Override public MageObject getSourceObjectIfItStillExists(Game game) { - MageObject currentObject = game.getObject(getSourceId()); - if (currentObject != null) { - if (sourceObject == null) { - setSourceObject(currentObject, game); - } - MageObjectReference mor = new MageObjectReference(currentObject, game); - if (mor.getZoneChangeCounter() == getSourceObjectZoneChangeCounter()) { - // source object has meanwhile not changed zone - return currentObject; - } + if (getSourceObjectZoneChangeCounter() == 0 + || getSourceObjectZoneChangeCounter() == game.getState().getZoneChangeCounter(getSourceId())) { + return game.getObject(getSourceId()); } return null; } @Override public Permanent getSourcePermanentIfItStillExists(Game game) { - if (sourceObject == null || !sourceObject.getId().equals(getSourceId())) { - setSourceObject(game.getObject(getSourceId()), game); - } - if (sourceObject instanceof Permanent) { - if (game.getState().getZoneChangeCounter(getSourceId()) == getSourceObjectZoneChangeCounter()) { - return (Permanent) sourceObject; - } + MageObject mageObject = getSourceObjectIfItStillExists(game); + if (mageObject instanceof Permanent) { + return (Permanent) mageObject; } return null; } @Override - public int getSourceObjectZoneChangeCounter() { - return sourceObjectZoneChangeCounter; + public Permanent getSourcePermanentOrLKI(Game game) { + if (getSourceObjectZoneChangeCounter() == 0 + || getSourceObjectZoneChangeCounter() == game.getState().getZoneChangeCounter(getSourceId())) { + return game.getPermanent(getSourceId()); + } + return (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD, getSourceObjectZoneChangeCounter()); } @Override - public void setSourceObject(MageObject sourceObject, Game game) { - if (sourceObject == null) { - this.sourceObject = game.getObject(sourceId); - this.sourceObjectZoneChangeCounter = game.getState().getZoneChangeCounter(sourceId); - } else { - this.sourceObject = sourceObject; - this.sourceObjectZoneChangeCounter = this.sourceObject.getZoneChangeCounter(game); - } + public void setSourceObjectZoneChangeCounter(int sourceObjectZoneChangeCounter) { + this.sourceObjectZoneChangeCounter = sourceObjectZoneChangeCounter; + } + + @Override + public int getSourceObjectZoneChangeCounter() { + return sourceObjectZoneChangeCounter; } @Override diff --git a/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java b/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java index e341ee74be..55e5bfb9c2 100644 --- a/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/TriggeredAbilityImpl.java @@ -1,4 +1,3 @@ - package mage.abilities; import java.util.Locale; @@ -45,9 +44,6 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge @Override public void trigger(Game game, UUID controllerId) { //20091005 - 603.4 - if (!(this instanceof DelayedTriggeredAbility)) { - setSourceObject(null, game); - } if (checkInterveningIfClause(game)) { game.addTriggeredAbility(this); } diff --git a/Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledToBattlefieldAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledToBattlefieldAbility.java index c7c465dd24..8ec64e7760 100644 --- a/Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledToBattlefieldAbility.java +++ b/Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledToBattlefieldAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.common.delayed; import java.util.LinkedHashSet; diff --git a/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceEffect.java index b4e9339de4..806acf2a7e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceEffect.java @@ -1,13 +1,12 @@ - package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.stack.Spell; /** * @@ -34,11 +33,9 @@ public class SacrificeSourceEffect extends OneShotEffect { MageObject sourceObject = source.getSourceObjectIfItStillExists(game); if (sourceObject == null) { // Check if the effect was installed by the spell the source was cast by (e.g. Necromancy), if not don't sacrifice the permanent - if (source.getSourceObject(game) instanceof Spell) { + if (game.getState().getZone(source.getSourceId()).equals(Zone.BATTLEFIELD) + && source.getSourceObjectZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(source.getSourceId())) { sourceObject = game.getPermanent(source.getSourceId()); - if (sourceObject != null && sourceObject.getZoneChangeCounter(game) > source.getSourceObjectZoneChangeCounter() + 1) { - return false; - } } } if (sourceObject instanceof Permanent) { diff --git a/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java b/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java index ebd11af1fb..1f0723298d 100644 --- a/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java @@ -1,6 +1,5 @@ package mage.abilities.meta; -import mage.MageObject; import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; @@ -14,9 +13,12 @@ import java.util.List; import java.util.UUID; /** - * A triggered ability that combines several others and triggers whenever one or more of them would. The abilities - * passed in should have null as their effect, and should have their own targets set if necessary. All other information - * will be passed in from changes to this Ability. Note: this does NOT work with abilities that have intervening if clauses. + * A triggered ability that combines several others and triggers whenever one or + * more of them would. The abilities passed in should have null as their effect, + * and should have their own targets set if necessary. All other information + * will be passed in from changes to this Ability. Note: this does NOT work with + * abilities that have intervening if clauses. + * * @author noahg */ public class OrTriggeredAbility extends TriggeredAbilityImpl { @@ -43,18 +45,17 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl { public OrTriggeredAbility(OrTriggeredAbility ability) { super(ability); this.triggeredAbilities = new TriggeredAbility[ability.triggeredAbilities.length]; - for (int i = 0; i < this.triggeredAbilities.length; i++){ + for (int i = 0; i < this.triggeredAbilities.length; i++) { this.triggeredAbilities[i] = ability.triggeredAbilities[i].copy(); } this.triggeringAbilities = new ArrayList<>(ability.triggeringAbilities); this.ruleTrigger = ability.ruleTrigger; } - @Override public boolean checkEventType(GameEvent event, Game game) { for (TriggeredAbility ability : triggeredAbilities) { - if (ability.checkEventType(event, game)){ + if (ability.checkEventType(event, game)) { System.out.println("Correct event type (" + event.getType() + ")"); return true; } @@ -101,7 +102,6 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl { return sb.toString() + super.getRule(); } - @Override public void setControllerId(UUID controllerId) { super.setControllerId(controllerId); @@ -126,11 +126,4 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl { } } - @Override - public void setSourceObject(MageObject sourceObject, Game game) { - super.setSourceObject(sourceObject, game); - for (TriggeredAbility ability : triggeredAbilities) { - ability.setSourceObject(sourceObject, game); - } - } } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index e745c75e12..18747ba2cf 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -1527,7 +1527,7 @@ public abstract class GameImpl implements Game, Serializable { @Override public void addEffect(ContinuousEffect continuousEffect, Ability source) { Ability newAbility = source.copy(); - newAbility.setSourceObject(null, this); // Update the source object to the currently existing Object + newAbility.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(source.getSourceId())); ContinuousEffect newEffect = continuousEffect.copy(); newEffect.newId(); @@ -1698,11 +1698,17 @@ public abstract class GameImpl implements Game, Serializable { if (ability instanceof TriggeredManaAbility || ability instanceof DelayedTriggeredManaAbility) { // 20110715 - 605.4 Ability manaAbiltiy = ability.copy(); + if (manaAbiltiy.getSourceObjectZoneChangeCounter() == 0) { + manaAbiltiy.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(ability.getSourceId())); + } manaAbiltiy.activate(this, false); manaAbiltiy.resolve(this); } else { TriggeredAbility newAbility = ability.copy(); newAbility.newId(); + if (newAbility.getSourceObjectZoneChangeCounter() == 0) { + newAbility.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(ability.getSourceId())); + } state.addTriggeredAbility(newAbility); } } @@ -1711,10 +1717,10 @@ public abstract class GameImpl implements Game, Serializable { public UUID addDelayedTriggeredAbility(DelayedTriggeredAbility delayedAbility, Ability source) { delayedAbility.setSourceId(source.getSourceId()); delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(this), this); // return addDelayedTriggeredAbility(delayedAbility); DelayedTriggeredAbility newAbility = delayedAbility.copy(); newAbility.newId(); + newAbility.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(source.getSourceId())); newAbility.initOnAdding(this); // ability.init is called as the ability triggeres not now. // If a FixedTarget pointer is already set from the effect setting up this delayed ability diff --git a/Mage/src/main/java/mage/game/command/Emblem.java b/Mage/src/main/java/mage/game/command/Emblem.java index 898a5aeb56..d95cfb659d 100644 --- a/Mage/src/main/java/mage/game/command/Emblem.java +++ b/Mage/src/main/java/mage/game/command/Emblem.java @@ -1,4 +1,3 @@ - package mage.game.command; import java.util.EnumSet; diff --git a/Mage/src/main/java/mage/game/command/Plane.java b/Mage/src/main/java/mage/game/command/Plane.java index b6a3768c29..ae34edade0 100644 --- a/Mage/src/main/java/mage/game/command/Plane.java +++ b/Mage/src/main/java/mage/game/command/Plane.java @@ -1,7 +1,5 @@ - package mage.game.command; -import static java.lang.Math.log; import java.lang.reflect.Constructor; import java.util.EnumSet; import java.util.List; @@ -289,7 +287,7 @@ public class Plane implements CommandObject { if (plane instanceof Plane) { return (Plane) plane; } - } catch (Exception ex) { + } catch (Exception ex) { } return null; } diff --git a/Mage/src/main/java/mage/game/stack/StackAbility.java b/Mage/src/main/java/mage/game/stack/StackAbility.java index 4c7259ed7d..02546c99c2 100644 --- a/Mage/src/main/java/mage/game/stack/StackAbility.java +++ b/Mage/src/main/java/mage/game/stack/StackAbility.java @@ -518,14 +518,19 @@ public class StackAbility extends StackObjImpl implements Ability { return this.ability.getSourcePermanentIfItStillExists(game); } + @Override + public void setSourceObjectZoneChangeCounter(int zoneChangeCounter) { + ability.setSourceObjectZoneChangeCounter(zoneChangeCounter); + } + @Override public int getSourceObjectZoneChangeCounter() { return ability.getSourceObjectZoneChangeCounter(); } @Override - public void setSourceObject(MageObject sourceObject, Game game) { - throw new UnsupportedOperationException("Not supported."); + public Permanent getSourcePermanentOrLKI(Game game) { + return ability.getSourcePermanentOrLKI(game); } @Override diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 42eebc64e7..efc4c7b977 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1041,15 +1041,15 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference permittingObject) { - if (game == null || ability == null) { + public boolean cast(SpellAbility originalAbility, Game game, boolean noMana, MageObjectReference permittingObject) { + if (game == null || originalAbility == null) { return false; } // Use ability copy to avoid problems with targets and costs on recast (issue https://github.com/magefree/mage/issues/5189). - ability = ability.copy(); - + SpellAbility ability = originalAbility.copy(); ability.setControllerId(getId()); + ability.setSourceObjectZoneChangeCounter(game.getState().getZoneChangeCounter(ability.getSourceId())); if (ability.getSpellAbilityType() != SpellAbilityType.BASE) { ability = chooseSpellAbilityForCast(ability, game, noMana); if (ability == null) { @@ -1073,6 +1073,8 @@ public abstract class PlayerImpl implements Player, Serializable { logger.error("Got no spell from stack. ability: " + ability.getRule()); return false; } + // Update the zcc to the stack + ability.setSourceObjectZoneChangeCounter(game.getState().getZoneChangeCounter(ability.getSourceId())); // some effects set sourceId to cast without paying mana costs or other costs if (ability.getSourceId().equals(getCastSourceIdWithAlternateMana())) { Ability spellAbility = spell.getSpellAbility(); From 99b4cacf33512cf56e3ddce63234289b66404d60 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 25 Oct 2018 12:48:33 +0200 Subject: [PATCH 076/167] * Changed maven project definition to use protoc-jar-maven-plugin. --- Mage/pom.xml | 109 ++++++++++++++------------------------------------- 1 file changed, 30 insertions(+), 79 deletions(-) diff --git a/Mage/pom.xml b/Mage/pom.xml index d7881372f8..5666f64aff 100644 --- a/Mage/pom.xml +++ b/Mage/pom.xml @@ -38,7 +38,7 @@ com.google.protobuf protobuf-java - ${protobuf.version} + 3.6.0 @@ -55,68 +55,31 @@ - - + - org.apache.maven.plugins - maven-dependency-plugin - ${maven-dependency-plugin.version} + com.github.os72 + protoc-jar-maven-plugin + 3.6.0.1 - copy-protoc - generate-sources - - copy - - - - - com.google.protobuf - protoc - ${protobuf.version} - ${os.detected.classifier} - exe - true - ${project.build.directory} - - - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - ${maven-antrun-plugin.version} - - - exec-protoc - generate-sources - - - - - - - - - - - - - - - - - - - - - - - run - + generate-sources + + run + + + + com.google.protobuf:protoc:3.0.0 + + ${project.basedir}/src/main/proto + + + + java + none + ${project.build.directory}/generated-sources + + + @@ -124,7 +87,7 @@ org.codehaus.mojo build-helper-maven-plugin - ${build-helper-maven-plugin.version} + 1.12 add-classes @@ -139,20 +102,16 @@ - + + + + + mage - - - - - kr.motd.maven - os-maven-plugin - ${os-maven-plugin.version} - - + @@ -160,14 +119,6 @@ ${project.basedir}/src/main/proto ${project.build.directory}/generated-sources - - - 1.9.1 - 1.8 - 2.10 - 2.4.2 - 1.4.1.Final - 3.0.0-beta-1 From cdcbf0aaa279b6cae711816d627136e48f65d8c7 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 25 Oct 2018 14:23:27 +0200 Subject: [PATCH 077/167] * Mistveil Plains - Fixed that the card was not moved to library. --- Mage.Sets/src/mage/cards/m/MistveilPlains.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MistveilPlains.java b/Mage.Sets/src/mage/cards/m/MistveilPlains.java index f564de722b..35d71a4487 100644 --- a/Mage.Sets/src/mage/cards/m/MistveilPlains.java +++ b/Mage.Sets/src/mage/cards/m/MistveilPlains.java @@ -1,6 +1,6 @@ - package mage.cards.m; +import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; @@ -20,8 +20,6 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; -import java.util.UUID; - /** * @author LevelX2 */ @@ -86,8 +84,8 @@ class MistveilPlainsGraveyardToLibraryEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Card card = game.getCard(source.getFirstTarget()); Player player = game.getPlayer(source.getControllerId()); - if (card == null || player == null || - game.getState().getZone(card.getId()) == Zone.GRAVEYARD) { + if (card == null || player == null + || game.getState().getZone(card.getId()) != Zone.GRAVEYARD) { return false; } return player.putCardsOnBottomOfLibrary(card, game, source, false); From 7fef8113c01267f6d4f2abfad5f27da1969cbbd3 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 25 Oct 2018 14:32:35 +0200 Subject: [PATCH 078/167] * Sylvan Library - Fixed that the order of the cards put back to library was random. --- Mage.Sets/src/mage/cards/s/SylvanLibrary.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SylvanLibrary.java b/Mage.Sets/src/mage/cards/s/SylvanLibrary.java index 97a7e02a0b..751a5ab544 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanLibrary.java +++ b/Mage.Sets/src/mage/cards/s/SylvanLibrary.java @@ -1,4 +1,3 @@ - package mage.cards.s; import java.util.HashMap; @@ -106,7 +105,7 @@ class SylvanLibraryEffect extends OneShotEffect { } } } - controller.putCardsOnTopOfLibrary(cardsPutBack, game, source, false); + controller.putCardsOnTopOfLibrary(cardsPutBack, game, source, true); } } return true; From 52f0ae8bd5e249cc7181f8e37533491abf4d56a7 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 25 Oct 2018 15:03:18 +0200 Subject: [PATCH 079/167] * Whispering Snitch - Fixed that it also triggered if other players surveilled. --- Mage.Sets/src/mage/cards/m/MissionBriefing.java | 10 ++++------ Mage.Sets/src/mage/cards/w/WhisperingSnitch.java | 9 ++++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MissionBriefing.java b/Mage.Sets/src/mage/cards/m/MissionBriefing.java index ecd3f55643..29642c0d63 100644 --- a/Mage.Sets/src/mage/cards/m/MissionBriefing.java +++ b/Mage.Sets/src/mage/cards/m/MissionBriefing.java @@ -13,7 +13,6 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.FilterCard; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; import mage.game.events.GameEvent; @@ -48,14 +47,12 @@ public final class MissionBriefing extends CardImpl { class MissionBriefingEffect extends OneShotEffect { - public static final FilterCard filter = new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard"); - public MissionBriefingEffect() { super(Outcome.Benefit); this.staticText = "Surveil 2, then choose an instant or sorcery card " + "in your graveyard. You may cast that card this turn. " + "If that card would be put into your graveyard this turn, " - + "exile it instead."; + + "exile it instead"; } public MissionBriefingEffect(final MissionBriefingEffect effect) { @@ -74,9 +71,10 @@ class MissionBriefingEffect extends OneShotEffect { return false; } player.surveil(2, source, game); - Target target = new TargetCardInYourGraveyard(filter); + Target target = new TargetCardInYourGraveyard( + new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard")); if (!player.choose(outcome, target, source.getSourceId(), game)) { - return false; + return true; } Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/cards/w/WhisperingSnitch.java b/Mage.Sets/src/mage/cards/w/WhisperingSnitch.java index c28daf0841..6d88e9d1af 100644 --- a/Mage.Sets/src/mage/cards/w/WhisperingSnitch.java +++ b/Mage.Sets/src/mage/cards/w/WhisperingSnitch.java @@ -7,10 +7,10 @@ import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.WatcherScope; import mage.constants.Zone; @@ -65,8 +65,11 @@ class WhisperingSnitchTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - WhisperingSnitchWatcher watcher = (WhisperingSnitchWatcher) game.getState().getWatchers().get(WhisperingSnitchWatcher.class.getSimpleName()); - return watcher != null && watcher.getTimesSurveiled(getControllerId()) == 1; + if (event.getPlayerId().equals(getControllerId())) { + WhisperingSnitchWatcher watcher = (WhisperingSnitchWatcher) game.getState().getWatchers().get(WhisperingSnitchWatcher.class.getSimpleName()); + return watcher != null && watcher.getTimesSurveiled(getControllerId()) == 1; + } + return false; } @Override From 44d32760463024e21568568405c87f2cf966564d Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 25 Oct 2018 16:15:24 +0200 Subject: [PATCH 080/167] * Brilliant Ultimatum - Fixed that it was not checked if the player is still allowed to play a land. --- .../src/mage/cards/b/BrilliantUltimatum.java | 2 +- Mage.Sets/src/mage/cards/w/WordOfCommand.java | 7 +-- .../java/mage/abilities/PlayLandAbility.java | 6 +- Mage/src/main/java/mage/players/Player.java | 62 +++++++++---------- .../main/java/mage/players/PlayerImpl.java | 10 ++- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java b/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java index c9bad9c5c7..4dc433e7c1 100644 --- a/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java +++ b/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java @@ -1,4 +1,3 @@ - package mage.cards.b; import java.util.ArrayList; @@ -111,6 +110,7 @@ class BrilliantUltimatumEffect extends OneShotEffect { TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard()); if (controller.chooseTarget(Outcome.PlayForFree, selectedPile, targetExiledCard, source, game)) { Card card = selectedPile.get(targetExiledCard.getFirstTarget(), game); + controller.canPlayLand(); if (controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game))) { selectedPileCards.remove(card); selectedPile.remove(card); diff --git a/Mage.Sets/src/mage/cards/w/WordOfCommand.java b/Mage.Sets/src/mage/cards/w/WordOfCommand.java index a73cc01035..ad06e245df 100644 --- a/Mage.Sets/src/mage/cards/w/WordOfCommand.java +++ b/Mage.Sets/src/mage/cards/w/WordOfCommand.java @@ -1,4 +1,3 @@ - package mage.cards.w; import java.util.UUID; @@ -14,8 +13,8 @@ import mage.abilities.effects.RestrictionEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; import mage.constants.AsThoughEffectType; +import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; @@ -37,7 +36,7 @@ import mage.target.targetpointer.FixedTarget; public final class WordOfCommand extends CardImpl { public WordOfCommand(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{B}"); // Look at target opponent's hand and choose a card from it. You control that player until Word of Command finishes resolving. The player plays that card if able. While doing so, the player can activate mana abilities only if they're from lands that player controls and only if mana they produce is spent to activate other mana abilities of lands the player controls and/or to play that card. If the chosen card is cast as a spell, you control the player while that spell is resolving. this.getSpellAbility().addEffect(new WordOfCommandEffect()); @@ -58,7 +57,7 @@ class WordOfCommandEffect extends OneShotEffect { public WordOfCommandEffect() { super(Outcome.GainControl); - this.staticText = "Look at target opponent's hand and choose a card from it. You control that player until Word of Command finishes resolving. The player plays that card if able. While doing so, the player can activate mana abilities only if they're from lands that player controls and only if mana they produce is spent to activate other mana abilities of lands the player controls and/or to play that card. If the chosen card is cast as a spell, you control the player while that spell is resolving"; + this.staticText = "Look at target opponent's hand and choose a card from it. You control that player until {this} finishes resolving. The player plays that card if able. While doing so, the player can activate mana abilities only if they're from lands that player controls and only if mana they produce is spent to activate other mana abilities of lands the player controls and/or to play that card. If the chosen card is cast as a spell, you control the player while that spell is resolving"; } public WordOfCommandEffect(final WordOfCommandEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/PlayLandAbility.java b/Mage/src/main/java/mage/abilities/PlayLandAbility.java index 939f28e328..4fc440012e 100644 --- a/Mage/src/main/java/mage/abilities/PlayLandAbility.java +++ b/Mage/src/main/java/mage/abilities/PlayLandAbility.java @@ -1,4 +1,3 @@ - package mage.abilities; import java.util.UUID; @@ -31,7 +30,10 @@ public class PlayLandAbility extends ActivatedAbilityImpl { return ActivationStatus.getFalse(); } //20091005 - 114.2a - return new ActivationStatus(game.isActivePlayer(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId), permittingObject); + return new ActivationStatus(game.isActivePlayer(playerId) + && game.getPlayer(playerId).canPlayLand() + && game.canPlaySorcery(playerId), + permittingObject); } @Override diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index a730164f73..1aa52abe55 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -1,5 +1,7 @@ package mage.players; +import java.io.Serializable; +import java.util.*; import mage.MageItem; import mage.MageObject; import mage.MageObjectReference; @@ -37,9 +39,6 @@ import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; import mage.util.Copyable; -import java.io.Serializable; -import java.util.*; - /** * @author BetaSteward_at_googlemail.com */ @@ -74,7 +73,7 @@ public interface Player extends MageItem, Copyable { void setLife(int life, Game game, UUID sourceId); /** - * @param amount amount of life loss + * @param amount amount of life loss * @param game * @param atCombat was the source combat damage * @return @@ -345,7 +344,7 @@ public interface Player extends MageItem, Copyable { * @param target * @param game * @param targetPlayerId player whose library will be searched - * @param triggerEvents whether searching will trigger any game events + * @param triggerEvents whether searching will trigger any game events * @return true if search was successful */ boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId, boolean triggerEvents); @@ -355,22 +354,23 @@ public interface Player extends MageItem, Copyable { /** * Plays a card if possible * - * @param card the card that can be cast + * @param card the card that can be cast * @param game - * @param noMana if it's a spell i can be cast without paying mana + * @param noMana if it's a spell i can be cast without paying mana * @param ignoreTiming if it's cast during the resolution of another spell - * no sorcery or play land timing restriction are checked. For a land it has - * to be the turn of the player playing that card. + * no sorcery or play land timing restriction are checked. For a land it has + * to be the turn of the player playing that card. + * @param reference mage object that allows to play the card * @return */ boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming, MageObjectReference reference); /** - * @param card the land card to play + * @param card the land card to play * @param game * @param ignoreTiming false - it won't be checked if the stack is empty and - * you are able to play a Sorcery. It's still checked, if you are able to - * play a land concerning the numner of lands you already played. + * you are able to play a Sorcery. It's still checked, if you are able to + * play a land concerning the number of lands you already played. * @return */ boolean playLand(Card card, Game game, boolean ignoreTiming); @@ -516,11 +516,11 @@ public interface Player extends MageItem, Copyable { /** * Moves the cards from cards to the bottom of the players library. * - * @param cards - list of cards that have to be moved - * @param game - game + * @param cards - list of cards that have to be moved + * @param game - game * @param anyOrder - true if player can determine the order of the cards - * else random order - * @param source - source ability + * else random order + * @param source - source ability * @return */ boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder); @@ -541,10 +541,10 @@ public interface Player extends MageItem, Copyable { /** * Moves the cards from cards to the top of players library. * - * @param cards - list of cards that have to be moved - * @param game - game + * @param cards - list of cards that have to be moved + * @param game - game * @param anyOrder - true if player can determine the order of the cards - * @param source - source ability + * @param source - source ability * @return */ boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder); @@ -570,8 +570,8 @@ public interface Player extends MageItem, Copyable { /** * Choose the order in which blockers get damage assigned to * - * @param blockers list of blockers where to choose the next one from - * @param combatGroup the concerning combat group + * @param blockers list of blockers where to choose the next one from + * @param combatGroup the concerning combat group * @param blockerOrder the already set order of blockers * @param game * @return blocker next to add to the blocker order @@ -710,11 +710,11 @@ public interface Player extends MageItem, Copyable { * @param toZone * @param source * @param game - * @param tapped the cards are tapped on the battlefield - * @param faceDown the cards are face down in the to zone - * @param byOwner the card is moved (or put onto battlefield) by the owner - * of the card and if target zone is battlefield controls the permanent - * (instead of the controller of the source) + * @param tapped the cards are tapped on the battlefield + * @param faceDown the cards are face down in the to zone + * @param byOwner the card is moved (or put onto battlefield) by the owner + * of the card and if target zone is battlefield controls the permanent + * (instead of the controller of the source) * @param appliedEffects * @return */ @@ -750,7 +750,7 @@ public interface Player extends MageItem, Copyable { * list of applied effects is not saved * * @param card - * @param exileId exile zone id (optional) + * @param exileId exile zone id (optional) * @param exileName name of exile zone (optional) * @param sourceId * @param game @@ -792,7 +792,7 @@ public interface Player extends MageItem, Copyable { * @param sourceId * @param game * @param fromZone if null, this info isn't postet - * @param toTop to the top of the library else to the bottom + * @param toTop to the top of the library else to the bottom * @param withName show the card name in the log * @return */ @@ -817,10 +817,10 @@ public interface Player extends MageItem, Copyable { * without mana (null) or the mana set to manaCosts instead of its normal * mana costs. * - * @param sourceId the source that can be cast without mana + * @param sourceId the source that can be cast without mana * @param manaCosts alternate ManaCost, null if it can be cast without mana - * cost - * @param costs alternate other costs you need to pay + * cost + * @param costs alternate other costs you need to pay */ void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts manaCosts, Costs costs); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index efc4c7b977..a3ad806816 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1145,8 +1145,14 @@ public abstract class PlayerImpl implements Player, Serializable { } //20091005 - 114.2a ActivationStatus activationStatus = playLandAbility.canActivate(this.playerId, game); - if (!ignoreTiming && !activationStatus.canActivate()) { - return false; + if (ignoreTiming) { + if (!canPlayLand()) { + return false; // ignore timing does not mean that more lands than normal can be played + } + } else { + if (!activationStatus.canActivate()) { + return false; + } } //20091005 - 305.1 From dd32a463ecb59eeb9ae5dd22f6a7a54e097107ec Mon Sep 17 00:00:00 2001 From: garypwn Date: Thu, 25 Oct 2018 17:44:15 -0700 Subject: [PATCH 081/167] Fix Commander Ninjutsu --- Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java b/Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java index 5737f0b50b..ce728b1f75 100644 --- a/Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java @@ -199,8 +199,8 @@ class RevealNinjutsuCardCost extends CostImpl { for (CommandObject coj : game.getState().getCommand()) { if (coj != null && coj.getId().equals(ability.getSourceId())) { card = game.getCard(ability.getSourceId()); + break; } - break; } } if (card != null) { From 22364300ee15849a2730296f6ed96e486a4ceb05 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 26 Oct 2018 15:35:55 -0500 Subject: [PATCH 082/167] - Added Opal Titan and Opal Acrolith. --- Mage.Sets/src/mage/cards/o/OpalAcrolith.java | 144 ++++ Mage.Sets/src/mage/cards/o/OpalTitan.java | 149 ++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 726 ++++++++++--------- 3 files changed, 657 insertions(+), 362 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/o/OpalAcrolith.java create mode 100644 Mage.Sets/src/mage/cards/o/OpalTitan.java diff --git a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java new file mode 100644 index 0000000000..9ffae411bd --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java @@ -0,0 +1,144 @@ +package mage.cards.o; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.effects.common.continuous.SourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.DependencyType; +import mage.constants.Duration; +import mage.constants.Layer; +import static mage.constants.Layer.TypeChangingEffects_4; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class OpalAcrolith extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("creature spell"); + + static { + filter.add(new CardTypePredicate(CardType.CREATURE)); + } + + public OpalAcrolith(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + + // Whenever an opponent casts a creature spell, if Opal Acrolith is an enchantment, Opal Acrolith becomes a 2/4 Soldier creature. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalAcrolithSoldier(), "", Duration.WhileOnBattlefield, true, false), + filter, false); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "Whenever an opponent casts a creature spell, if Opal Acrolith is an enchantment, Opal Acrolith becomes a 2/4 Soldier creature.")); + + // {0}: Opal Acrolith becomes an enchantment. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesEnchantmentSourceEffect(CardType.ENCHANTMENT), new ManaCostsImpl("{0}"))); + + } + + public OpalAcrolith(final OpalAcrolith card) { + super(card); + } + + @Override + public OpalAcrolith copy() { + return new OpalAcrolith(this); + } +} + +class BecomesEnchantmentSourceEffect extends ContinuousEffectImpl implements SourceEffect { + + public BecomesEnchantmentSourceEffect(CardType cardType) { + super(Duration.Custom, Outcome.AddAbility); + staticText = "Opal Acrolith becomes an Enchantment"; + dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); + + } + + public BecomesEnchantmentSourceEffect(final BecomesEnchantmentSourceEffect effect) { + super(effect); + } + + @Override + public BecomesEnchantmentSourceEffect copy() { + return new BecomesEnchantmentSourceEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + Permanent permanent = affectedObjectList.get(0).getPermanent(game); + if (permanent != null) { + switch (layer) { + case TypeChangingEffects_4: + if (sublayer == SubLayer.NA) { + permanent.getCardType().clear(); + permanent.getSubtype(game).clear(); + if (!permanent.getCardType().contains(CardType.ENCHANTMENT)) { + permanent.getCardType().add(CardType.ENCHANTMENT); + } + } + break; + } + return true; + } + this.discard(); + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return Layer.TypeChangingEffects_4 == layer; + } + +} + +class OpalAcrolithSoldier extends TokenImpl { + + public OpalAcrolithSoldier() { + super("Soldier", "2/4 Ape creature"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.SOLDIER); + power = new MageInt(2); + toughness = new MageInt(4); + } + + public OpalAcrolithSoldier(final OpalAcrolithSoldier token) { + super(token); + } + + public OpalAcrolithSoldier copy() { + return new OpalAcrolithSoldier(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OpalTitan.java b/Mage.Sets/src/mage/cards/o/OpalTitan.java new file mode 100644 index 0000000000..8f9655f1d8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OpalTitan.java @@ -0,0 +1,149 @@ +package mage.cards.o; + +import java.util.UUID; +import mage.MageObjectReference; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.continuous.SourceEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.DependencyType; +import mage.constants.Duration; +import mage.constants.Layer; +import static mage.constants.Layer.AbilityAddingRemovingEffects_6; +import static mage.constants.Layer.PTChangingEffects_7; +import static mage.constants.Layer.TypeChangingEffects_4; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.constants.SubLayer; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; + +/** + * + * @author jeffwadsworth + */ +public final class OpalTitan extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("creature spell"); + + static { + filter.add(new CardTypePredicate(CardType.CREATURE)); + } + + public OpalTitan(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); + + // When an opponent casts a creature spell, if Opal Titan is an enchantment, Opal Titan becomes a 4/4 Giant creature with protection from each of that spell's colors. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, new OpalTitanBecomesCreatureEffect(), + filter, false, SetTargetPointer.SPELL); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "When an opponent casts a creature spell, if Opal Titan is an enchantment, Opal Titan becomes a 4/4 Giant creature with protection from each of that spell's colors.")); + + } + + public OpalTitan(final OpalTitan card) { + super(card); + } + + @Override + public OpalTitan copy() { + return new OpalTitan(this); + } +} + +class OpalTitanBecomesCreatureEffect extends ContinuousEffectImpl implements SourceEffect { + + public OpalTitanBecomesCreatureEffect() { + super(Duration.WhileOnBattlefield, Outcome.BecomeCreature); + setText(); + this.addDependencyType(DependencyType.BecomeCreature); + } + + public OpalTitanBecomesCreatureEffect(final OpalTitanBecomesCreatureEffect effect) { + super(effect); + } + + @Override + public OpalTitanBecomesCreatureEffect copy() { + return new OpalTitanBecomesCreatureEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); + Spell creatureSpellCast = game.getSpell(targetPointer.getFirst(game, source)); + if (creatureSpellCast != null + && creatureSpellCast.getColor(game).hasColor()) { + game.getState().setValue("opalTitanColor" + source.getSourceId(), creatureSpellCast.getColor(game)); + } + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + Permanent permanent = affectedObjectList.get(0).getPermanent(game); + if (permanent != null) { + switch (layer) { + case TypeChangingEffects_4: + if (sublayer == SubLayer.NA) { + permanent.getCardType().clear(); + permanent.addCardType(CardType.CREATURE); + permanent.getSubtype(game).add(SubType.GIANT); + } + break; + case AbilityAddingRemovingEffects_6: + if (sublayer == SubLayer.NA) { + if (((ObjectColor) game.getState().getValue("opalTitanColor" + source.getSourceId())) != null) { + for (ObjectColor color : ((ObjectColor) game.getState().getValue("opalTitanColor" + source.getSourceId())).getColors()) { + if (!permanent.getAbilities().contains(ProtectionAbility.from(color))) { + permanent.addAbility(ProtectionAbility.from(color)); + } + } + } + } + break; + case PTChangingEffects_7: + if ((sublayer == SubLayer.CharacteristicDefining_7a) + || (sublayer == SubLayer.SetPT_7b)) { + permanent.getPower().setValue(4); + permanent.getToughness().setValue(4); + } + break; + } + return true; + } + this.discard(); + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + private void setText() { + staticText = duration.toString() + " {this} becomes a 4/4 Giant creature with protection from each of that spell's colors"; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.PTChangingEffects_7 + || layer == Layer.AbilityAddingRemovingEffects_6 + || layer == Layer.TypeChangingEffects_4; + } + +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 161a5e42ca..f4cabc7989 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -1,362 +1,364 @@ -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author Backfir3 - */ -public final class UrzasSaga extends ExpansionSet { - - private static final UrzasSaga instance = new UrzasSaga(); - - public static UrzasSaga getInstance() { - return instance; - } - - private UrzasSaga() { - super("Urza's Saga", "USG", ExpansionSet.buildDate(1998, 10, 12), SetType.EXPANSION); - this.blockName = "Urza"; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Absolute Grace", 1, Rarity.UNCOMMON, mage.cards.a.AbsoluteGrace.class)); - cards.add(new SetCardInfo("Absolute Law", 2, Rarity.UNCOMMON, mage.cards.a.AbsoluteLaw.class)); - cards.add(new SetCardInfo("Abundance", 229, Rarity.RARE, mage.cards.a.Abundance.class)); - cards.add(new SetCardInfo("Abyssal Horror", 115, Rarity.RARE, mage.cards.a.AbyssalHorror.class)); - cards.add(new SetCardInfo("Academy Researchers", 58, Rarity.UNCOMMON, mage.cards.a.AcademyResearchers.class)); - cards.add(new SetCardInfo("Acidic Soil", 172, Rarity.UNCOMMON, mage.cards.a.AcidicSoil.class)); - cards.add(new SetCardInfo("Acridian", 230, Rarity.COMMON, mage.cards.a.Acridian.class)); - cards.add(new SetCardInfo("Albino Troll", 231, Rarity.UNCOMMON, mage.cards.a.AlbinoTroll.class)); - cards.add(new SetCardInfo("Anaconda", 232, Rarity.UNCOMMON, mage.cards.a.Anaconda.class)); - cards.add(new SetCardInfo("Angelic Chorus", 3, Rarity.RARE, mage.cards.a.AngelicChorus.class)); - cards.add(new SetCardInfo("Angelic Page", 4, Rarity.COMMON, mage.cards.a.AngelicPage.class)); - cards.add(new SetCardInfo("Annul", 59, Rarity.COMMON, mage.cards.a.Annul.class)); - cards.add(new SetCardInfo("Arcane Laboratory", 60, Rarity.UNCOMMON, mage.cards.a.ArcaneLaboratory.class)); - cards.add(new SetCardInfo("Arc Lightning", 174, Rarity.COMMON, mage.cards.a.ArcLightning.class)); - cards.add(new SetCardInfo("Argothian Elder", 233, Rarity.UNCOMMON, mage.cards.a.ArgothianElder.class)); - cards.add(new SetCardInfo("Argothian Enchantress", 234, Rarity.RARE, mage.cards.a.ArgothianEnchantress.class)); - cards.add(new SetCardInfo("Argothian Swine", 235, Rarity.COMMON, mage.cards.a.ArgothianSwine.class)); - cards.add(new SetCardInfo("Argothian Wurm", 236, Rarity.RARE, mage.cards.a.ArgothianWurm.class)); - cards.add(new SetCardInfo("Attunement", 61, Rarity.RARE, mage.cards.a.Attunement.class)); - cards.add(new SetCardInfo("Back to Basics", 62, Rarity.RARE, mage.cards.b.BackToBasics.class)); - cards.add(new SetCardInfo("Barrin, Master Wizard", 63, Rarity.RARE, mage.cards.b.BarrinMasterWizard.class)); - cards.add(new SetCardInfo("Barrin's Codex", 286, Rarity.RARE, mage.cards.b.BarrinsCodex.class)); - cards.add(new SetCardInfo("Bedlam", 175, Rarity.RARE, mage.cards.b.Bedlam.class)); - cards.add(new SetCardInfo("Befoul", 116, Rarity.COMMON, mage.cards.b.Befoul.class)); - cards.add(new SetCardInfo("Bereavement", 117, Rarity.UNCOMMON, mage.cards.b.Bereavement.class)); - cards.add(new SetCardInfo("Blanchwood Armor", 237, Rarity.UNCOMMON, mage.cards.b.BlanchwoodArmor.class)); - cards.add(new SetCardInfo("Blanchwood Treefolk", 238, Rarity.COMMON, mage.cards.b.BlanchwoodTreefolk.class)); - cards.add(new SetCardInfo("Blasted Landscape", 319, Rarity.UNCOMMON, mage.cards.b.BlastedLandscape.class)); - cards.add(new SetCardInfo("Blood Vassal", 118, Rarity.COMMON, mage.cards.b.BloodVassal.class)); - cards.add(new SetCardInfo("Bog Raiders", 119, Rarity.COMMON, mage.cards.b.BogRaiders.class)); - cards.add(new SetCardInfo("Brand", 176, Rarity.RARE, mage.cards.b.Brand.class)); - cards.add(new SetCardInfo("Bravado", 177, Rarity.COMMON, mage.cards.b.Bravado.class)); - cards.add(new SetCardInfo("Breach", 120, Rarity.COMMON, mage.cards.b.Breach.class)); - cards.add(new SetCardInfo("Brilliant Halo", 5, Rarity.COMMON, mage.cards.b.BrilliantHalo.class)); - cards.add(new SetCardInfo("Bull Hippo", 239, Rarity.UNCOMMON, mage.cards.b.BullHippo.class)); - cards.add(new SetCardInfo("Bulwark", 178, Rarity.RARE, mage.cards.b.Bulwark.class)); - cards.add(new SetCardInfo("Cackling Fiend", 121, Rarity.COMMON, mage.cards.c.CacklingFiend.class)); - cards.add(new SetCardInfo("Carpet of Flowers", 240, Rarity.UNCOMMON, mage.cards.c.CarpetOfFlowers.class)); - cards.add(new SetCardInfo("Carrion Beetles", 122, Rarity.COMMON, mage.cards.c.CarrionBeetles.class)); - cards.add(new SetCardInfo("Catalog", 64, Rarity.COMMON, mage.cards.c.Catalog.class)); - cards.add(new SetCardInfo("Catastrophe", 6, Rarity.RARE, mage.cards.c.Catastrophe.class)); - cards.add(new SetCardInfo("Cathodion", 287, Rarity.UNCOMMON, mage.cards.c.Cathodion.class)); - cards.add(new SetCardInfo("Cave Tiger", 241, Rarity.COMMON, mage.cards.c.CaveTiger.class)); - cards.add(new SetCardInfo("Child of Gaea", 242, Rarity.RARE, mage.cards.c.ChildOfGaea.class)); - cards.add(new SetCardInfo("Chimeric Staff", 288, Rarity.RARE, mage.cards.c.ChimericStaff.class)); - cards.add(new SetCardInfo("Citanul Centaurs", 243, Rarity.RARE, mage.cards.c.CitanulCentaurs.class)); - cards.add(new SetCardInfo("Citanul Flute", 289, Rarity.RARE, mage.cards.c.CitanulFlute.class)); - cards.add(new SetCardInfo("Citanul Hierophants", 244, Rarity.RARE, mage.cards.c.CitanulHierophants.class)); - cards.add(new SetCardInfo("Claws of Gix", 290, Rarity.UNCOMMON, mage.cards.c.ClawsOfGix.class)); - cards.add(new SetCardInfo("Clear", 7, Rarity.UNCOMMON, mage.cards.c.Clear.class)); - cards.add(new SetCardInfo("Cloak of Mists", 65, Rarity.COMMON, mage.cards.c.CloakOfMists.class)); - cards.add(new SetCardInfo("Confiscate", 66, Rarity.UNCOMMON, mage.cards.c.Confiscate.class)); - cards.add(new SetCardInfo("Congregate", 8, Rarity.COMMON, mage.cards.c.Congregate.class)); - cards.add(new SetCardInfo("Contamination", 123, Rarity.RARE, mage.cards.c.Contamination.class)); - cards.add(new SetCardInfo("Copper Gnomes", 291, Rarity.RARE, mage.cards.c.CopperGnomes.class)); - cards.add(new SetCardInfo("Coral Merfolk", 67, Rarity.COMMON, mage.cards.c.CoralMerfolk.class)); - cards.add(new SetCardInfo("Corrupt", 124, Rarity.COMMON, mage.cards.c.Corrupt.class)); - cards.add(new SetCardInfo("Cradle Guard", 245, Rarity.UNCOMMON, mage.cards.c.CradleGuard.class)); - cards.add(new SetCardInfo("Crater Hellion", 179, Rarity.RARE, mage.cards.c.CraterHellion.class)); - cards.add(new SetCardInfo("Crazed Skirge", 125, Rarity.UNCOMMON, mage.cards.c.CrazedSkirge.class)); - cards.add(new SetCardInfo("Crosswinds", 246, Rarity.UNCOMMON, mage.cards.c.Crosswinds.class)); - cards.add(new SetCardInfo("Crystal Chimes", 292, Rarity.UNCOMMON, mage.cards.c.CrystalChimes.class)); - cards.add(new SetCardInfo("Curfew", 68, Rarity.COMMON, mage.cards.c.Curfew.class)); - cards.add(new SetCardInfo("Darkest Hour", 128, Rarity.RARE, mage.cards.d.DarkestHour.class)); - cards.add(new SetCardInfo("Dark Hatchling", 126, Rarity.RARE, mage.cards.d.DarkHatchling.class)); - cards.add(new SetCardInfo("Dark Ritual", 127, Rarity.COMMON, mage.cards.d.DarkRitual.class)); - cards.add(new SetCardInfo("Defensive Formation", 9, Rarity.UNCOMMON, mage.cards.d.DefensiveFormation.class)); - cards.add(new SetCardInfo("Despondency", 129, Rarity.COMMON, mage.cards.d.Despondency.class)); - cards.add(new SetCardInfo("Destructive Urge", 180, Rarity.UNCOMMON, mage.cards.d.DestructiveUrge.class)); - cards.add(new SetCardInfo("Diabolic Servitude", 130, Rarity.UNCOMMON, mage.cards.d.DiabolicServitude.class)); - cards.add(new SetCardInfo("Disciple of Grace", 10, Rarity.COMMON, mage.cards.d.DiscipleOfGrace.class)); - cards.add(new SetCardInfo("Disciple of Law", 11, Rarity.COMMON, mage.cards.d.DiscipleOfLaw.class)); - cards.add(new SetCardInfo("Disenchant", 12, Rarity.COMMON, mage.cards.d.Disenchant.class)); - cards.add(new SetCardInfo("Disorder", 181, Rarity.UNCOMMON, mage.cards.d.Disorder.class)); - cards.add(new SetCardInfo("Disruptive Student", 69, Rarity.COMMON, mage.cards.d.DisruptiveStudent.class)); - cards.add(new SetCardInfo("Douse", 70, Rarity.UNCOMMON, mage.cards.d.Douse.class)); - cards.add(new SetCardInfo("Dragon Blood", 293, Rarity.UNCOMMON, mage.cards.d.DragonBlood.class)); - cards.add(new SetCardInfo("Drifting Djinn", 71, Rarity.RARE, mage.cards.d.DriftingDjinn.class)); - cards.add(new SetCardInfo("Drifting Meadow", 320, Rarity.COMMON, mage.cards.d.DriftingMeadow.class)); - cards.add(new SetCardInfo("Dromosaur", 182, Rarity.COMMON, mage.cards.d.Dromosaur.class)); - cards.add(new SetCardInfo("Duress", 132, Rarity.COMMON, mage.cards.d.Duress.class)); - cards.add(new SetCardInfo("Eastern Paladin", 133, Rarity.RARE, mage.cards.e.EasternPaladin.class)); - cards.add(new SetCardInfo("Electryte", 183, Rarity.RARE, mage.cards.e.Electryte.class)); - cards.add(new SetCardInfo("Elite Archers", 13, Rarity.RARE, mage.cards.e.EliteArchers.class)); - cards.add(new SetCardInfo("Elvish Herder", 247, Rarity.COMMON, mage.cards.e.ElvishHerder.class)); - cards.add(new SetCardInfo("Elvish Lyrist", 248, Rarity.COMMON, mage.cards.e.ElvishLyrist.class)); - cards.add(new SetCardInfo("Endless Wurm", 249, Rarity.RARE, mage.cards.e.EndlessWurm.class)); - cards.add(new SetCardInfo("Endoskeleton", 294, Rarity.UNCOMMON, mage.cards.e.Endoskeleton.class)); - cards.add(new SetCardInfo("Energy Field", 73, Rarity.RARE, mage.cards.e.EnergyField.class)); - cards.add(new SetCardInfo("Exhaustion", 74, Rarity.UNCOMMON, mage.cards.e.Exhaustion.class)); - cards.add(new SetCardInfo("Exhume", 134, Rarity.COMMON, mage.cards.e.Exhume.class)); - cards.add(new SetCardInfo("Exploration", 250, Rarity.RARE, mage.cards.e.Exploration.class)); - cards.add(new SetCardInfo("Expunge", 135, Rarity.COMMON, mage.cards.e.Expunge.class)); - cards.add(new SetCardInfo("Faith Healer", 14, Rarity.RARE, mage.cards.f.FaithHealer.class)); - cards.add(new SetCardInfo("Falter", 184, Rarity.COMMON, mage.cards.f.Falter.class)); - cards.add(new SetCardInfo("Fault Line", 185, Rarity.RARE, mage.cards.f.FaultLine.class)); - cards.add(new SetCardInfo("Fecundity", 251, Rarity.UNCOMMON, mage.cards.f.Fecundity.class)); - cards.add(new SetCardInfo("Fertile Ground", 252, Rarity.COMMON, mage.cards.f.FertileGround.class)); - cards.add(new SetCardInfo("Fiery Mantle", 186, Rarity.COMMON, mage.cards.f.FieryMantle.class)); - cards.add(new SetCardInfo("Fire Ants", 187, Rarity.UNCOMMON, mage.cards.f.FireAnts.class)); - cards.add(new SetCardInfo("Flesh Reaver", 136, Rarity.UNCOMMON, mage.cards.f.FleshReaver.class)); - cards.add(new SetCardInfo("Fluctuator", 295, Rarity.RARE, mage.cards.f.Fluctuator.class)); - cards.add(new SetCardInfo("Fog Bank", 75, Rarity.UNCOMMON, mage.cards.f.FogBank.class)); - cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 348, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 349, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 350, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Fortitude", 253, Rarity.COMMON, mage.cards.f.Fortitude.class)); - cards.add(new SetCardInfo("Gaea's Bounty", 254, Rarity.COMMON, mage.cards.g.GaeasBounty.class)); - cards.add(new SetCardInfo("Gaea's Cradle", 321, Rarity.RARE, mage.cards.g.GaeasCradle.class)); - cards.add(new SetCardInfo("Gaea's Embrace", 255, Rarity.UNCOMMON, mage.cards.g.GaeasEmbrace.class)); - cards.add(new SetCardInfo("Gamble", 188, Rarity.RARE, mage.cards.g.Gamble.class)); - cards.add(new SetCardInfo("Gilded Drake", 76, Rarity.RARE, mage.cards.g.GildedDrake.class)); - cards.add(new SetCardInfo("Glorious Anthem", 15, Rarity.RARE, mage.cards.g.GloriousAnthem.class)); - cards.add(new SetCardInfo("Goblin Cadets", 189, Rarity.UNCOMMON, mage.cards.g.GoblinCadets.class)); - cards.add(new SetCardInfo("Goblin Lackey", 190, Rarity.UNCOMMON, mage.cards.g.GoblinLackey.class)); - cards.add(new SetCardInfo("Goblin Matron", 191, Rarity.COMMON, mage.cards.g.GoblinMatron.class)); - cards.add(new SetCardInfo("Goblin Offensive", 192, Rarity.UNCOMMON, mage.cards.g.GoblinOffensive.class)); - cards.add(new SetCardInfo("Goblin Patrol", 193, Rarity.COMMON, mage.cards.g.GoblinPatrol.class)); - cards.add(new SetCardInfo("Goblin Raider", 194, Rarity.COMMON, mage.cards.g.GoblinRaider.class)); - cards.add(new SetCardInfo("Goblin Spelunkers", 195, Rarity.COMMON, mage.cards.g.GoblinSpelunkers.class)); - cards.add(new SetCardInfo("Goblin War Buggy", 196, Rarity.COMMON, mage.cards.g.GoblinWarBuggy.class)); - cards.add(new SetCardInfo("Gorilla Warrior", 256, Rarity.COMMON, mage.cards.g.GorillaWarrior.class)); - cards.add(new SetCardInfo("Grafted Skullcap", 296, Rarity.RARE, mage.cards.g.GraftedSkullcap.class)); - cards.add(new SetCardInfo("Greater Good", 257, Rarity.RARE, mage.cards.g.GreaterGood.class)); - cards.add(new SetCardInfo("Great Whale", 77, Rarity.RARE, mage.cards.g.GreatWhale.class)); - cards.add(new SetCardInfo("Greener Pastures", 258, Rarity.RARE, mage.cards.g.GreenerPastures.class)); - cards.add(new SetCardInfo("Guma", 197, Rarity.UNCOMMON, mage.cards.g.Guma.class)); - cards.add(new SetCardInfo("Hawkeater Moth", 259, Rarity.UNCOMMON, mage.cards.h.HawkeaterMoth.class)); - cards.add(new SetCardInfo("Headlong Rush", 198, Rarity.COMMON, mage.cards.h.HeadlongRush.class)); - cards.add(new SetCardInfo("Healing Salve", 16, Rarity.COMMON, mage.cards.h.HealingSalve.class)); - cards.add(new SetCardInfo("Heat Ray", 199, Rarity.COMMON, mage.cards.h.HeatRay.class)); - cards.add(new SetCardInfo("Herald of Serra", 17, Rarity.RARE, mage.cards.h.HeraldOfSerra.class)); - cards.add(new SetCardInfo("Hermetic Study", 78, Rarity.COMMON, mage.cards.h.HermeticStudy.class)); - cards.add(new SetCardInfo("Hibernation", 79, Rarity.UNCOMMON, mage.cards.h.Hibernation.class)); - cards.add(new SetCardInfo("Hidden Ancients", 260, Rarity.UNCOMMON, mage.cards.h.HiddenAncients.class)); - cards.add(new SetCardInfo("Hidden Guerrillas", 261, Rarity.UNCOMMON, mage.cards.h.HiddenGuerrillas.class)); - cards.add(new SetCardInfo("Hidden Herd", 262, Rarity.RARE, mage.cards.h.HiddenHerd.class)); - cards.add(new SetCardInfo("Hidden Spider", 264, Rarity.COMMON, mage.cards.h.HiddenSpider.class)); - cards.add(new SetCardInfo("Hollow Dogs", 137, Rarity.COMMON, mage.cards.h.HollowDogs.class)); - cards.add(new SetCardInfo("Hopping Automaton", 297, Rarity.UNCOMMON, mage.cards.h.HoppingAutomaton.class)); - cards.add(new SetCardInfo("Horseshoe Crab", 80, Rarity.COMMON, mage.cards.h.HorseshoeCrab.class)); - cards.add(new SetCardInfo("Humble", 18, Rarity.UNCOMMON, mage.cards.h.Humble.class)); - cards.add(new SetCardInfo("Hush", 266, Rarity.COMMON, mage.cards.h.Hush.class)); - cards.add(new SetCardInfo("Ill-Gotten Gains", 138, Rarity.RARE, mage.cards.i.IllGottenGains.class)); - cards.add(new SetCardInfo("Imaginary Pet", 81, Rarity.RARE, mage.cards.i.ImaginaryPet.class)); - cards.add(new SetCardInfo("Intrepid Hero", 19, Rarity.RARE, mage.cards.i.IntrepidHero.class)); - cards.add(new SetCardInfo("Island", 335, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 336, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Jagged Lightning", 200, Rarity.UNCOMMON, mage.cards.j.JaggedLightning.class)); - cards.add(new SetCardInfo("Karn, Silver Golem", 298, Rarity.RARE, mage.cards.k.KarnSilverGolem.class)); - cards.add(new SetCardInfo("Launch", 82, Rarity.COMMON, mage.cards.l.Launch.class)); - cards.add(new SetCardInfo("Lay Waste", 201, Rarity.COMMON, mage.cards.l.LayWaste.class)); - cards.add(new SetCardInfo("Lifeline", 299, Rarity.RARE, mage.cards.l.Lifeline.class)); - cards.add(new SetCardInfo("Lightning Dragon", 202, Rarity.RARE, mage.cards.l.LightningDragon.class)); - cards.add(new SetCardInfo("Lilting Refrain", 83, Rarity.UNCOMMON, mage.cards.l.LiltingRefrain.class)); - cards.add(new SetCardInfo("Lingering Mirage", 84, Rarity.UNCOMMON, mage.cards.l.LingeringMirage.class)); - cards.add(new SetCardInfo("Looming Shade", 139, Rarity.COMMON, mage.cards.l.LoomingShade.class)); - cards.add(new SetCardInfo("Lotus Blossom", 300, Rarity.RARE, mage.cards.l.LotusBlossom.class)); - cards.add(new SetCardInfo("Lull", 267, Rarity.COMMON, mage.cards.l.Lull.class)); - cards.add(new SetCardInfo("Lurking Evil", 140, Rarity.RARE, mage.cards.l.LurkingEvil.class)); - cards.add(new SetCardInfo("Mana Leech", 141, Rarity.UNCOMMON, mage.cards.m.ManaLeech.class)); - cards.add(new SetCardInfo("Meltdown", 203, Rarity.UNCOMMON, mage.cards.m.Meltdown.class)); - cards.add(new SetCardInfo("Metrognome", 301, Rarity.RARE, mage.cards.m.Metrognome.class)); - cards.add(new SetCardInfo("Midsummer Revel", 268, Rarity.RARE, mage.cards.m.MidsummerRevel.class)); - cards.add(new SetCardInfo("Mishra's Helix", 302, Rarity.RARE, mage.cards.m.MishrasHelix.class)); - cards.add(new SetCardInfo("Mobile Fort", 303, Rarity.UNCOMMON, mage.cards.m.MobileFort.class)); - cards.add(new SetCardInfo("Monk Idealist", 20, Rarity.UNCOMMON, mage.cards.m.MonkIdealist.class)); - cards.add(new SetCardInfo("Monk Realist", 21, Rarity.COMMON, mage.cards.m.MonkRealist.class)); - cards.add(new SetCardInfo("Morphling", 85, Rarity.RARE, mage.cards.m.Morphling.class)); - cards.add(new SetCardInfo("Mountain", 343, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 344, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 345, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("No Rest for the Wicked", 142, Rarity.UNCOMMON, mage.cards.n.NoRestForTheWicked.class)); - cards.add(new SetCardInfo("Noetic Scales", 304, Rarity.RARE, mage.cards.n.NoeticScales.class)); - cards.add(new SetCardInfo("Okk", 204, Rarity.RARE, mage.cards.o.Okk.class)); - cards.add(new SetCardInfo("Opal Archangel", 23, Rarity.RARE, mage.cards.o.OpalArchangel.class)); - cards.add(new SetCardInfo("Opal Caryatid", 24, Rarity.COMMON, mage.cards.o.OpalCaryatid.class)); - cards.add(new SetCardInfo("Opal Gargoyle", 25, Rarity.COMMON, mage.cards.o.OpalGargoyle.class)); - cards.add(new SetCardInfo("Oppression", 143, Rarity.RARE, mage.cards.o.Oppression.class)); - cards.add(new SetCardInfo("Order of Yawgmoth", 144, Rarity.UNCOMMON, mage.cards.o.OrderOfYawgmoth.class)); - cards.add(new SetCardInfo("Pacifism", 27, Rarity.COMMON, mage.cards.p.Pacifism.class)); - cards.add(new SetCardInfo("Parasitic Bond", 145, Rarity.UNCOMMON, mage.cards.p.ParasiticBond.class)); - cards.add(new SetCardInfo("Pariah", 28, Rarity.RARE, mage.cards.p.Pariah.class)); - cards.add(new SetCardInfo("Path of Peace", 29, Rarity.COMMON, mage.cards.p.PathOfPeace.class)); - cards.add(new SetCardInfo("Pegasus Charger", 30, Rarity.COMMON, mage.cards.p.PegasusCharger.class)); - cards.add(new SetCardInfo("Pendrell Drake", 86, Rarity.COMMON, mage.cards.p.PendrellDrake.class)); - cards.add(new SetCardInfo("Pendrell Flux", 87, Rarity.COMMON, mage.cards.p.PendrellFlux.class)); - cards.add(new SetCardInfo("Peregrine Drake", 88, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); - cards.add(new SetCardInfo("Persecute", 146, Rarity.RARE, mage.cards.p.Persecute.class)); - cards.add(new SetCardInfo("Pestilence", 147, Rarity.COMMON, mage.cards.p.Pestilence.class)); - cards.add(new SetCardInfo("Phyrexian Colossus", 305, Rarity.RARE, mage.cards.p.PhyrexianColossus.class)); - cards.add(new SetCardInfo("Phyrexian Ghoul", 148, Rarity.COMMON, mage.cards.p.PhyrexianGhoul.class)); - cards.add(new SetCardInfo("Phyrexian Processor", 306, Rarity.RARE, mage.cards.p.PhyrexianProcessor.class)); - cards.add(new SetCardInfo("Phyrexian Tower", 322, Rarity.RARE, mage.cards.p.PhyrexianTower.class)); - cards.add(new SetCardInfo("Pit Trap", 307, Rarity.UNCOMMON, mage.cards.p.PitTrap.class)); - cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Planar Birth", 31, Rarity.RARE, mage.cards.p.PlanarBirth.class)); - cards.add(new SetCardInfo("Planar Void", 149, Rarity.UNCOMMON, mage.cards.p.PlanarVoid.class)); - cards.add(new SetCardInfo("Polluted Mire", 323, Rarity.COMMON, mage.cards.p.PollutedMire.class)); - cards.add(new SetCardInfo("Pouncing Jaguar", 269, Rarity.COMMON, mage.cards.p.PouncingJaguar.class)); - cards.add(new SetCardInfo("Power Sink", 89, Rarity.COMMON, mage.cards.p.PowerSink.class)); - cards.add(new SetCardInfo("Presence of the Master", 32, Rarity.UNCOMMON, mage.cards.p.PresenceOfTheMaster.class)); - cards.add(new SetCardInfo("Priest of Gix", 150, Rarity.UNCOMMON, mage.cards.p.PriestOfGix.class)); - cards.add(new SetCardInfo("Priest of Titania", 270, Rarity.COMMON, mage.cards.p.PriestOfTitania.class)); - cards.add(new SetCardInfo("Purging Scythe", 308, Rarity.RARE, mage.cards.p.PurgingScythe.class)); - cards.add(new SetCardInfo("Rain of Filth", 151, Rarity.UNCOMMON, mage.cards.r.RainOfFilth.class)); - cards.add(new SetCardInfo("Rain of Salt", 206, Rarity.UNCOMMON, mage.cards.r.RainOfSalt.class)); - cards.add(new SetCardInfo("Ravenous Skirge", 152, Rarity.COMMON, mage.cards.r.RavenousSkirge.class)); - cards.add(new SetCardInfo("Raze", 207, Rarity.COMMON, mage.cards.r.Raze.class)); - cards.add(new SetCardInfo("Recantation", 91, Rarity.RARE, mage.cards.r.Recantation.class)); - cards.add(new SetCardInfo("Reclusive Wight", 153, Rarity.UNCOMMON, mage.cards.r.ReclusiveWight.class)); - cards.add(new SetCardInfo("Redeem", 33, Rarity.UNCOMMON, mage.cards.r.Redeem.class)); - cards.add(new SetCardInfo("Reflexes", 208, Rarity.COMMON, mage.cards.r.Reflexes.class)); - cards.add(new SetCardInfo("Rejuvenate", 271, Rarity.COMMON, mage.cards.r.Rejuvenate.class)); - cards.add(new SetCardInfo("Remembrance", 34, Rarity.RARE, mage.cards.r.Remembrance.class)); - cards.add(new SetCardInfo("Remote Isle", 324, Rarity.COMMON, mage.cards.r.RemoteIsle.class)); - cards.add(new SetCardInfo("Reprocess", 154, Rarity.RARE, mage.cards.r.Reprocess.class)); - cards.add(new SetCardInfo("Rescind", 92, Rarity.COMMON, mage.cards.r.Rescind.class)); - cards.add(new SetCardInfo("Retaliation", 272, Rarity.UNCOMMON, mage.cards.r.Retaliation.class)); - cards.add(new SetCardInfo("Retromancer", 209, Rarity.COMMON, mage.cards.r.Retromancer.class)); - cards.add(new SetCardInfo("Rewind", 93, Rarity.COMMON, mage.cards.r.Rewind.class)); - cards.add(new SetCardInfo("Rumbling Crescendo", 210, Rarity.RARE, mage.cards.r.RumblingCrescendo.class)); - cards.add(new SetCardInfo("Rune of Protection: Artifacts", 35, Rarity.UNCOMMON, mage.cards.r.RuneOfProtectionArtifacts.class)); - cards.add(new SetCardInfo("Rune of Protection: Black", 36, Rarity.COMMON, mage.cards.r.RuneOfProtectionBlack.class)); - cards.add(new SetCardInfo("Rune of Protection: Blue", 37, Rarity.COMMON, mage.cards.r.RuneOfProtectionBlue.class)); - cards.add(new SetCardInfo("Rune of Protection: Green", 38, Rarity.COMMON, mage.cards.r.RuneOfProtectionGreen.class)); - cards.add(new SetCardInfo("Rune of Protection: Lands", 39, Rarity.RARE, mage.cards.r.RuneOfProtectionLands.class)); - cards.add(new SetCardInfo("Rune of Protection: Red", 40, Rarity.COMMON, mage.cards.r.RuneOfProtectionRed.class)); - cards.add(new SetCardInfo("Rune of Protection: White", 41, Rarity.COMMON, mage.cards.r.RuneOfProtectionWhite.class)); - cards.add(new SetCardInfo("Sanctum Custodian", 42, Rarity.COMMON, mage.cards.s.SanctumCustodian.class)); - cards.add(new SetCardInfo("Sanctum Guardian", 43, Rarity.UNCOMMON, mage.cards.s.SanctumGuardian.class)); - cards.add(new SetCardInfo("Sandbar Merfolk", 94, Rarity.COMMON, mage.cards.s.SandbarMerfolk.class)); - cards.add(new SetCardInfo("Sandbar Serpent", 95, Rarity.UNCOMMON, mage.cards.s.SandbarSerpent.class)); - cards.add(new SetCardInfo("Sanguine Guard", 155, Rarity.UNCOMMON, mage.cards.s.SanguineGuard.class)); - cards.add(new SetCardInfo("Scald", 211, Rarity.UNCOMMON, mage.cards.s.Scald.class)); - cards.add(new SetCardInfo("Scoria Wurm", 212, Rarity.RARE, mage.cards.s.ScoriaWurm.class)); - cards.add(new SetCardInfo("Scrap", 213, Rarity.COMMON, mage.cards.s.Scrap.class)); - cards.add(new SetCardInfo("Seasoned Marshal", 44, Rarity.UNCOMMON, mage.cards.s.SeasonedMarshal.class)); - cards.add(new SetCardInfo("Serra Avatar", 45, Rarity.RARE, mage.cards.s.SerraAvatar.class)); - cards.add(new SetCardInfo("Serra's Embrace", 47, Rarity.UNCOMMON, mage.cards.s.SerrasEmbrace.class)); - cards.add(new SetCardInfo("Serra's Liturgy", 49, Rarity.RARE, mage.cards.s.SerrasLiturgy.class)); - cards.add(new SetCardInfo("Serra's Sanctum", 325, Rarity.RARE, mage.cards.s.SerrasSanctum.class)); - cards.add(new SetCardInfo("Serra Zealot", 46, Rarity.COMMON, mage.cards.s.SerraZealot.class)); - cards.add(new SetCardInfo("Shimmering Barrier", 50, Rarity.UNCOMMON, mage.cards.s.ShimmeringBarrier.class)); - cards.add(new SetCardInfo("Shivan Gorge", 326, Rarity.RARE, mage.cards.s.ShivanGorge.class)); - cards.add(new SetCardInfo("Shivan Hellkite", 214, Rarity.RARE, mage.cards.s.ShivanHellkite.class)); - cards.add(new SetCardInfo("Shivan Raptor", 215, Rarity.UNCOMMON, mage.cards.s.ShivanRaptor.class)); - cards.add(new SetCardInfo("Shiv's Embrace", 216, Rarity.UNCOMMON, mage.cards.s.ShivsEmbrace.class)); - cards.add(new SetCardInfo("Show and Tell", 96, Rarity.RARE, mage.cards.s.ShowAndTell.class)); - cards.add(new SetCardInfo("Shower of Sparks", 217, Rarity.COMMON, mage.cards.s.ShowerOfSparks.class)); - cards.add(new SetCardInfo("Sicken", 156, Rarity.COMMON, mage.cards.s.Sicken.class)); - cards.add(new SetCardInfo("Silent Attendant", 51, Rarity.COMMON, mage.cards.s.SilentAttendant.class)); - cards.add(new SetCardInfo("Skirge Familiar", 157, Rarity.UNCOMMON, mage.cards.s.SkirgeFamiliar.class)); - cards.add(new SetCardInfo("Skittering Skirge", 158, Rarity.COMMON, mage.cards.s.SkitteringSkirge.class)); - cards.add(new SetCardInfo("Sleeper Agent", 159, Rarity.RARE, mage.cards.s.SleeperAgent.class)); - cards.add(new SetCardInfo("Slippery Karst", 327, Rarity.COMMON, mage.cards.s.SlipperyKarst.class)); - cards.add(new SetCardInfo("Smokestack", 309, Rarity.RARE, mage.cards.s.Smokestack.class)); - cards.add(new SetCardInfo("Smoldering Crater", 328, Rarity.COMMON, mage.cards.s.SmolderingCrater.class)); - cards.add(new SetCardInfo("Sneak Attack", 218, Rarity.RARE, mage.cards.s.SneakAttack.class)); - cards.add(new SetCardInfo("Somnophore", 97, Rarity.RARE, mage.cards.s.Somnophore.class)); - cards.add(new SetCardInfo("Songstitcher", 52, Rarity.UNCOMMON, mage.cards.s.Songstitcher.class)); - cards.add(new SetCardInfo("Spined Fluke", 160, Rarity.UNCOMMON, mage.cards.s.SpinedFluke.class)); - cards.add(new SetCardInfo("Spire Owl", 98, Rarity.COMMON, mage.cards.s.SpireOwl.class)); - cards.add(new SetCardInfo("Sporogenesis", 273, Rarity.RARE, mage.cards.s.Sporogenesis.class)); - cards.add(new SetCardInfo("Spreading Algae", 274, Rarity.UNCOMMON, mage.cards.s.SpreadingAlgae.class)); - cards.add(new SetCardInfo("Steam Blast", 219, Rarity.UNCOMMON, mage.cards.s.SteamBlast.class)); - cards.add(new SetCardInfo("Stern Proctor", 99, Rarity.UNCOMMON, mage.cards.s.SternProctor.class)); - cards.add(new SetCardInfo("Stroke of Genius", 100, Rarity.RARE, mage.cards.s.StrokeOfGenius.class)); - cards.add(new SetCardInfo("Sulfuric Vapors", 220, Rarity.RARE, mage.cards.s.SulfuricVapors.class)); - cards.add(new SetCardInfo("Sunder", 101, Rarity.RARE, mage.cards.s.Sunder.class)); - cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 340, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 341, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 342, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Symbiosis", 275, Rarity.COMMON, mage.cards.s.Symbiosis.class)); - cards.add(new SetCardInfo("Tainted Aether", 161, Rarity.RARE, mage.cards.t.TaintedAether.class)); - cards.add(new SetCardInfo("Telepathy", 102, Rarity.UNCOMMON, mage.cards.t.Telepathy.class)); - cards.add(new SetCardInfo("Temporal Aperture", 310, Rarity.RARE, mage.cards.t.TemporalAperture.class)); - cards.add(new SetCardInfo("Thran Quarry", 329, Rarity.RARE, mage.cards.t.ThranQuarry.class)); - cards.add(new SetCardInfo("Thran Turbine", 311, Rarity.UNCOMMON, mage.cards.t.ThranTurbine.class)); - cards.add(new SetCardInfo("Thundering Giant", 221, Rarity.UNCOMMON, mage.cards.t.ThunderingGiant.class)); - cards.add(new SetCardInfo("Time Spiral", 103, Rarity.RARE, mage.cards.t.TimeSpiral.class)); - cards.add(new SetCardInfo("Titania's Boon", 276, Rarity.UNCOMMON, mage.cards.t.TitaniasBoon.class)); - cards.add(new SetCardInfo("Titania's Chosen", 277, Rarity.UNCOMMON, mage.cards.t.TitaniasChosen.class)); - cards.add(new SetCardInfo("Tolarian Academy", 330, Rarity.RARE, mage.cards.t.TolarianAcademy.class)); - cards.add(new SetCardInfo("Tolarian Winds", 104, Rarity.COMMON, mage.cards.t.TolarianWinds.class)); - cards.add(new SetCardInfo("Torch Song", 222, Rarity.UNCOMMON, mage.cards.t.TorchSong.class)); - cards.add(new SetCardInfo("Treefolk Seedlings", 278, Rarity.UNCOMMON, mage.cards.t.TreefolkSeedlings.class)); - cards.add(new SetCardInfo("Treetop Rangers", 279, Rarity.COMMON, mage.cards.t.TreetopRangers.class)); - cards.add(new SetCardInfo("Turnabout", 105, Rarity.UNCOMMON, mage.cards.t.Turnabout.class)); - cards.add(new SetCardInfo("Umbilicus", 312, Rarity.RARE, mage.cards.u.Umbilicus.class)); - cards.add(new SetCardInfo("Unnerve", 162, Rarity.COMMON, mage.cards.u.Unnerve.class)); - cards.add(new SetCardInfo("Unworthy Dead", 163, Rarity.COMMON, mage.cards.u.UnworthyDead.class)); - cards.add(new SetCardInfo("Urza's Armor", 313, Rarity.UNCOMMON, mage.cards.u.UrzasArmor.class)); - cards.add(new SetCardInfo("Vampiric Embrace", 164, Rarity.UNCOMMON, mage.cards.v.VampiricEmbrace.class)); - cards.add(new SetCardInfo("Vebulid", 165, Rarity.RARE, mage.cards.v.Vebulid.class)); - cards.add(new SetCardInfo("Vernal Bloom", 281, Rarity.RARE, mage.cards.v.VernalBloom.class)); - cards.add(new SetCardInfo("Viashino Outrider", 223, Rarity.COMMON, mage.cards.v.ViashinoOutrider.class)); - cards.add(new SetCardInfo("Viashino Runner", 224, Rarity.COMMON, mage.cards.v.ViashinoRunner.class)); - cards.add(new SetCardInfo("Viashino Sandswimmer", 225, Rarity.RARE, mage.cards.v.ViashinoSandswimmer.class)); - cards.add(new SetCardInfo("Viashino Weaponsmith", 226, Rarity.COMMON, mage.cards.v.ViashinoWeaponsmith.class)); - cards.add(new SetCardInfo("Victimize", 166, Rarity.UNCOMMON, mage.cards.v.Victimize.class)); - cards.add(new SetCardInfo("Vile Requiem", 167, Rarity.UNCOMMON, mage.cards.v.VileRequiem.class)); - cards.add(new SetCardInfo("Voice of Grace", 54, Rarity.UNCOMMON, mage.cards.v.VoiceOfGrace.class)); - cards.add(new SetCardInfo("Voice of Law", 55, Rarity.UNCOMMON, mage.cards.v.VoiceOfLaw.class)); - cards.add(new SetCardInfo("Voltaic Key", 314, Rarity.UNCOMMON, mage.cards.v.VoltaicKey.class)); - cards.add(new SetCardInfo("Vug Lizard", 227, Rarity.UNCOMMON, mage.cards.v.VugLizard.class)); - cards.add(new SetCardInfo("War Dance", 282, Rarity.UNCOMMON, mage.cards.w.WarDance.class)); - cards.add(new SetCardInfo("Wall of Junk", 315, Rarity.UNCOMMON, mage.cards.w.WallOfJunk.class)); - cards.add(new SetCardInfo("Waylay", 56, Rarity.UNCOMMON, mage.cards.w.Waylay.class)); - cards.add(new SetCardInfo("Western Paladin", 168, Rarity.RARE, mage.cards.w.WesternPaladin.class)); - cards.add(new SetCardInfo("Whetstone", 316, Rarity.RARE, mage.cards.w.Whetstone.class)); - cards.add(new SetCardInfo("Whirlwind", 283, Rarity.RARE, mage.cards.w.Whirlwind.class)); - cards.add(new SetCardInfo("Wild Dogs", 284, Rarity.COMMON, mage.cards.w.WildDogs.class)); - cards.add(new SetCardInfo("Wildfire", 228, Rarity.RARE, mage.cards.w.Wildfire.class)); - cards.add(new SetCardInfo("Windfall", 111, Rarity.UNCOMMON, mage.cards.w.Windfall.class)); - cards.add(new SetCardInfo("Winding Wurm", 285, Rarity.COMMON, mage.cards.w.WindingWurm.class)); - cards.add(new SetCardInfo("Wirecat", 317, Rarity.UNCOMMON, mage.cards.w.Wirecat.class)); - cards.add(new SetCardInfo("Witch Engine", 169, Rarity.RARE, mage.cards.w.WitchEngine.class)); - cards.add(new SetCardInfo("Wizard Mentor", 112, Rarity.COMMON, mage.cards.w.WizardMentor.class)); - cards.add(new SetCardInfo("Worn Powerstone", 318, Rarity.UNCOMMON, mage.cards.w.WornPowerstone.class)); - cards.add(new SetCardInfo("Worship", 57, Rarity.RARE, mage.cards.w.Worship.class)); - cards.add(new SetCardInfo("Yawgmoth's Edict", 170, Rarity.UNCOMMON, mage.cards.y.YawgmothsEdict.class)); - cards.add(new SetCardInfo("Yawgmoth's Will", 171, Rarity.RARE, mage.cards.y.YawgmothsWill.class)); - cards.add(new SetCardInfo("Zephid", 113, Rarity.RARE, mage.cards.z.Zephid.class)); - cards.add(new SetCardInfo("Zephid's Embrace", 114, Rarity.UNCOMMON, mage.cards.z.ZephidsEmbrace.class)); - } -} +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author Backfir3 + */ +public final class UrzasSaga extends ExpansionSet { + + private static final UrzasSaga instance = new UrzasSaga(); + + public static UrzasSaga getInstance() { + return instance; + } + + private UrzasSaga() { + super("Urza's Saga", "USG", ExpansionSet.buildDate(1998, 10, 12), SetType.EXPANSION); + this.blockName = "Urza"; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Absolute Grace", 1, Rarity.UNCOMMON, mage.cards.a.AbsoluteGrace.class)); + cards.add(new SetCardInfo("Absolute Law", 2, Rarity.UNCOMMON, mage.cards.a.AbsoluteLaw.class)); + cards.add(new SetCardInfo("Abundance", 229, Rarity.RARE, mage.cards.a.Abundance.class)); + cards.add(new SetCardInfo("Abyssal Horror", 115, Rarity.RARE, mage.cards.a.AbyssalHorror.class)); + cards.add(new SetCardInfo("Academy Researchers", 58, Rarity.UNCOMMON, mage.cards.a.AcademyResearchers.class)); + cards.add(new SetCardInfo("Acidic Soil", 172, Rarity.UNCOMMON, mage.cards.a.AcidicSoil.class)); + cards.add(new SetCardInfo("Acridian", 230, Rarity.COMMON, mage.cards.a.Acridian.class)); + cards.add(new SetCardInfo("Albino Troll", 231, Rarity.UNCOMMON, mage.cards.a.AlbinoTroll.class)); + cards.add(new SetCardInfo("Anaconda", 232, Rarity.UNCOMMON, mage.cards.a.Anaconda.class)); + cards.add(new SetCardInfo("Angelic Chorus", 3, Rarity.RARE, mage.cards.a.AngelicChorus.class)); + cards.add(new SetCardInfo("Angelic Page", 4, Rarity.COMMON, mage.cards.a.AngelicPage.class)); + cards.add(new SetCardInfo("Annul", 59, Rarity.COMMON, mage.cards.a.Annul.class)); + cards.add(new SetCardInfo("Arcane Laboratory", 60, Rarity.UNCOMMON, mage.cards.a.ArcaneLaboratory.class)); + cards.add(new SetCardInfo("Arc Lightning", 174, Rarity.COMMON, mage.cards.a.ArcLightning.class)); + cards.add(new SetCardInfo("Argothian Elder", 233, Rarity.UNCOMMON, mage.cards.a.ArgothianElder.class)); + cards.add(new SetCardInfo("Argothian Enchantress", 234, Rarity.RARE, mage.cards.a.ArgothianEnchantress.class)); + cards.add(new SetCardInfo("Argothian Swine", 235, Rarity.COMMON, mage.cards.a.ArgothianSwine.class)); + cards.add(new SetCardInfo("Argothian Wurm", 236, Rarity.RARE, mage.cards.a.ArgothianWurm.class)); + cards.add(new SetCardInfo("Attunement", 61, Rarity.RARE, mage.cards.a.Attunement.class)); + cards.add(new SetCardInfo("Back to Basics", 62, Rarity.RARE, mage.cards.b.BackToBasics.class)); + cards.add(new SetCardInfo("Barrin, Master Wizard", 63, Rarity.RARE, mage.cards.b.BarrinMasterWizard.class)); + cards.add(new SetCardInfo("Barrin's Codex", 286, Rarity.RARE, mage.cards.b.BarrinsCodex.class)); + cards.add(new SetCardInfo("Bedlam", 175, Rarity.RARE, mage.cards.b.Bedlam.class)); + cards.add(new SetCardInfo("Befoul", 116, Rarity.COMMON, mage.cards.b.Befoul.class)); + cards.add(new SetCardInfo("Bereavement", 117, Rarity.UNCOMMON, mage.cards.b.Bereavement.class)); + cards.add(new SetCardInfo("Blanchwood Armor", 237, Rarity.UNCOMMON, mage.cards.b.BlanchwoodArmor.class)); + cards.add(new SetCardInfo("Blanchwood Treefolk", 238, Rarity.COMMON, mage.cards.b.BlanchwoodTreefolk.class)); + cards.add(new SetCardInfo("Blasted Landscape", 319, Rarity.UNCOMMON, mage.cards.b.BlastedLandscape.class)); + cards.add(new SetCardInfo("Blood Vassal", 118, Rarity.COMMON, mage.cards.b.BloodVassal.class)); + cards.add(new SetCardInfo("Bog Raiders", 119, Rarity.COMMON, mage.cards.b.BogRaiders.class)); + cards.add(new SetCardInfo("Brand", 176, Rarity.RARE, mage.cards.b.Brand.class)); + cards.add(new SetCardInfo("Bravado", 177, Rarity.COMMON, mage.cards.b.Bravado.class)); + cards.add(new SetCardInfo("Breach", 120, Rarity.COMMON, mage.cards.b.Breach.class)); + cards.add(new SetCardInfo("Brilliant Halo", 5, Rarity.COMMON, mage.cards.b.BrilliantHalo.class)); + cards.add(new SetCardInfo("Bull Hippo", 239, Rarity.UNCOMMON, mage.cards.b.BullHippo.class)); + cards.add(new SetCardInfo("Bulwark", 178, Rarity.RARE, mage.cards.b.Bulwark.class)); + cards.add(new SetCardInfo("Cackling Fiend", 121, Rarity.COMMON, mage.cards.c.CacklingFiend.class)); + cards.add(new SetCardInfo("Carpet of Flowers", 240, Rarity.UNCOMMON, mage.cards.c.CarpetOfFlowers.class)); + cards.add(new SetCardInfo("Carrion Beetles", 122, Rarity.COMMON, mage.cards.c.CarrionBeetles.class)); + cards.add(new SetCardInfo("Catalog", 64, Rarity.COMMON, mage.cards.c.Catalog.class)); + cards.add(new SetCardInfo("Catastrophe", 6, Rarity.RARE, mage.cards.c.Catastrophe.class)); + cards.add(new SetCardInfo("Cathodion", 287, Rarity.UNCOMMON, mage.cards.c.Cathodion.class)); + cards.add(new SetCardInfo("Cave Tiger", 241, Rarity.COMMON, mage.cards.c.CaveTiger.class)); + cards.add(new SetCardInfo("Child of Gaea", 242, Rarity.RARE, mage.cards.c.ChildOfGaea.class)); + cards.add(new SetCardInfo("Chimeric Staff", 288, Rarity.RARE, mage.cards.c.ChimericStaff.class)); + cards.add(new SetCardInfo("Citanul Centaurs", 243, Rarity.RARE, mage.cards.c.CitanulCentaurs.class)); + cards.add(new SetCardInfo("Citanul Flute", 289, Rarity.RARE, mage.cards.c.CitanulFlute.class)); + cards.add(new SetCardInfo("Citanul Hierophants", 244, Rarity.RARE, mage.cards.c.CitanulHierophants.class)); + cards.add(new SetCardInfo("Claws of Gix", 290, Rarity.UNCOMMON, mage.cards.c.ClawsOfGix.class)); + cards.add(new SetCardInfo("Clear", 7, Rarity.UNCOMMON, mage.cards.c.Clear.class)); + cards.add(new SetCardInfo("Cloak of Mists", 65, Rarity.COMMON, mage.cards.c.CloakOfMists.class)); + cards.add(new SetCardInfo("Confiscate", 66, Rarity.UNCOMMON, mage.cards.c.Confiscate.class)); + cards.add(new SetCardInfo("Congregate", 8, Rarity.COMMON, mage.cards.c.Congregate.class)); + cards.add(new SetCardInfo("Contamination", 123, Rarity.RARE, mage.cards.c.Contamination.class)); + cards.add(new SetCardInfo("Copper Gnomes", 291, Rarity.RARE, mage.cards.c.CopperGnomes.class)); + cards.add(new SetCardInfo("Coral Merfolk", 67, Rarity.COMMON, mage.cards.c.CoralMerfolk.class)); + cards.add(new SetCardInfo("Corrupt", 124, Rarity.COMMON, mage.cards.c.Corrupt.class)); + cards.add(new SetCardInfo("Cradle Guard", 245, Rarity.UNCOMMON, mage.cards.c.CradleGuard.class)); + cards.add(new SetCardInfo("Crater Hellion", 179, Rarity.RARE, mage.cards.c.CraterHellion.class)); + cards.add(new SetCardInfo("Crazed Skirge", 125, Rarity.UNCOMMON, mage.cards.c.CrazedSkirge.class)); + cards.add(new SetCardInfo("Crosswinds", 246, Rarity.UNCOMMON, mage.cards.c.Crosswinds.class)); + cards.add(new SetCardInfo("Crystal Chimes", 292, Rarity.UNCOMMON, mage.cards.c.CrystalChimes.class)); + cards.add(new SetCardInfo("Curfew", 68, Rarity.COMMON, mage.cards.c.Curfew.class)); + cards.add(new SetCardInfo("Darkest Hour", 128, Rarity.RARE, mage.cards.d.DarkestHour.class)); + cards.add(new SetCardInfo("Dark Hatchling", 126, Rarity.RARE, mage.cards.d.DarkHatchling.class)); + cards.add(new SetCardInfo("Dark Ritual", 127, Rarity.COMMON, mage.cards.d.DarkRitual.class)); + cards.add(new SetCardInfo("Defensive Formation", 9, Rarity.UNCOMMON, mage.cards.d.DefensiveFormation.class)); + cards.add(new SetCardInfo("Despondency", 129, Rarity.COMMON, mage.cards.d.Despondency.class)); + cards.add(new SetCardInfo("Destructive Urge", 180, Rarity.UNCOMMON, mage.cards.d.DestructiveUrge.class)); + cards.add(new SetCardInfo("Diabolic Servitude", 130, Rarity.UNCOMMON, mage.cards.d.DiabolicServitude.class)); + cards.add(new SetCardInfo("Disciple of Grace", 10, Rarity.COMMON, mage.cards.d.DiscipleOfGrace.class)); + cards.add(new SetCardInfo("Disciple of Law", 11, Rarity.COMMON, mage.cards.d.DiscipleOfLaw.class)); + cards.add(new SetCardInfo("Disenchant", 12, Rarity.COMMON, mage.cards.d.Disenchant.class)); + cards.add(new SetCardInfo("Disorder", 181, Rarity.UNCOMMON, mage.cards.d.Disorder.class)); + cards.add(new SetCardInfo("Disruptive Student", 69, Rarity.COMMON, mage.cards.d.DisruptiveStudent.class)); + cards.add(new SetCardInfo("Douse", 70, Rarity.UNCOMMON, mage.cards.d.Douse.class)); + cards.add(new SetCardInfo("Dragon Blood", 293, Rarity.UNCOMMON, mage.cards.d.DragonBlood.class)); + cards.add(new SetCardInfo("Drifting Djinn", 71, Rarity.RARE, mage.cards.d.DriftingDjinn.class)); + cards.add(new SetCardInfo("Drifting Meadow", 320, Rarity.COMMON, mage.cards.d.DriftingMeadow.class)); + cards.add(new SetCardInfo("Dromosaur", 182, Rarity.COMMON, mage.cards.d.Dromosaur.class)); + cards.add(new SetCardInfo("Duress", 132, Rarity.COMMON, mage.cards.d.Duress.class)); + cards.add(new SetCardInfo("Eastern Paladin", 133, Rarity.RARE, mage.cards.e.EasternPaladin.class)); + cards.add(new SetCardInfo("Electryte", 183, Rarity.RARE, mage.cards.e.Electryte.class)); + cards.add(new SetCardInfo("Elite Archers", 13, Rarity.RARE, mage.cards.e.EliteArchers.class)); + cards.add(new SetCardInfo("Elvish Herder", 247, Rarity.COMMON, mage.cards.e.ElvishHerder.class)); + cards.add(new SetCardInfo("Elvish Lyrist", 248, Rarity.COMMON, mage.cards.e.ElvishLyrist.class)); + cards.add(new SetCardInfo("Endless Wurm", 249, Rarity.RARE, mage.cards.e.EndlessWurm.class)); + cards.add(new SetCardInfo("Endoskeleton", 294, Rarity.UNCOMMON, mage.cards.e.Endoskeleton.class)); + cards.add(new SetCardInfo("Energy Field", 73, Rarity.RARE, mage.cards.e.EnergyField.class)); + cards.add(new SetCardInfo("Exhaustion", 74, Rarity.UNCOMMON, mage.cards.e.Exhaustion.class)); + cards.add(new SetCardInfo("Exhume", 134, Rarity.COMMON, mage.cards.e.Exhume.class)); + cards.add(new SetCardInfo("Exploration", 250, Rarity.RARE, mage.cards.e.Exploration.class)); + cards.add(new SetCardInfo("Expunge", 135, Rarity.COMMON, mage.cards.e.Expunge.class)); + cards.add(new SetCardInfo("Faith Healer", 14, Rarity.RARE, mage.cards.f.FaithHealer.class)); + cards.add(new SetCardInfo("Falter", 184, Rarity.COMMON, mage.cards.f.Falter.class)); + cards.add(new SetCardInfo("Fault Line", 185, Rarity.RARE, mage.cards.f.FaultLine.class)); + cards.add(new SetCardInfo("Fecundity", 251, Rarity.UNCOMMON, mage.cards.f.Fecundity.class)); + cards.add(new SetCardInfo("Fertile Ground", 252, Rarity.COMMON, mage.cards.f.FertileGround.class)); + cards.add(new SetCardInfo("Fiery Mantle", 186, Rarity.COMMON, mage.cards.f.FieryMantle.class)); + cards.add(new SetCardInfo("Fire Ants", 187, Rarity.UNCOMMON, mage.cards.f.FireAnts.class)); + cards.add(new SetCardInfo("Flesh Reaver", 136, Rarity.UNCOMMON, mage.cards.f.FleshReaver.class)); + cards.add(new SetCardInfo("Fluctuator", 295, Rarity.RARE, mage.cards.f.Fluctuator.class)); + cards.add(new SetCardInfo("Fog Bank", 75, Rarity.UNCOMMON, mage.cards.f.FogBank.class)); + cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 348, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 349, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 350, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fortitude", 253, Rarity.COMMON, mage.cards.f.Fortitude.class)); + cards.add(new SetCardInfo("Gaea's Bounty", 254, Rarity.COMMON, mage.cards.g.GaeasBounty.class)); + cards.add(new SetCardInfo("Gaea's Cradle", 321, Rarity.RARE, mage.cards.g.GaeasCradle.class)); + cards.add(new SetCardInfo("Gaea's Embrace", 255, Rarity.UNCOMMON, mage.cards.g.GaeasEmbrace.class)); + cards.add(new SetCardInfo("Gamble", 188, Rarity.RARE, mage.cards.g.Gamble.class)); + cards.add(new SetCardInfo("Gilded Drake", 76, Rarity.RARE, mage.cards.g.GildedDrake.class)); + cards.add(new SetCardInfo("Glorious Anthem", 15, Rarity.RARE, mage.cards.g.GloriousAnthem.class)); + cards.add(new SetCardInfo("Goblin Cadets", 189, Rarity.UNCOMMON, mage.cards.g.GoblinCadets.class)); + cards.add(new SetCardInfo("Goblin Lackey", 190, Rarity.UNCOMMON, mage.cards.g.GoblinLackey.class)); + cards.add(new SetCardInfo("Goblin Matron", 191, Rarity.COMMON, mage.cards.g.GoblinMatron.class)); + cards.add(new SetCardInfo("Goblin Offensive", 192, Rarity.UNCOMMON, mage.cards.g.GoblinOffensive.class)); + cards.add(new SetCardInfo("Goblin Patrol", 193, Rarity.COMMON, mage.cards.g.GoblinPatrol.class)); + cards.add(new SetCardInfo("Goblin Raider", 194, Rarity.COMMON, mage.cards.g.GoblinRaider.class)); + cards.add(new SetCardInfo("Goblin Spelunkers", 195, Rarity.COMMON, mage.cards.g.GoblinSpelunkers.class)); + cards.add(new SetCardInfo("Goblin War Buggy", 196, Rarity.COMMON, mage.cards.g.GoblinWarBuggy.class)); + cards.add(new SetCardInfo("Gorilla Warrior", 256, Rarity.COMMON, mage.cards.g.GorillaWarrior.class)); + cards.add(new SetCardInfo("Grafted Skullcap", 296, Rarity.RARE, mage.cards.g.GraftedSkullcap.class)); + cards.add(new SetCardInfo("Greater Good", 257, Rarity.RARE, mage.cards.g.GreaterGood.class)); + cards.add(new SetCardInfo("Great Whale", 77, Rarity.RARE, mage.cards.g.GreatWhale.class)); + cards.add(new SetCardInfo("Greener Pastures", 258, Rarity.RARE, mage.cards.g.GreenerPastures.class)); + cards.add(new SetCardInfo("Guma", 197, Rarity.UNCOMMON, mage.cards.g.Guma.class)); + cards.add(new SetCardInfo("Hawkeater Moth", 259, Rarity.UNCOMMON, mage.cards.h.HawkeaterMoth.class)); + cards.add(new SetCardInfo("Headlong Rush", 198, Rarity.COMMON, mage.cards.h.HeadlongRush.class)); + cards.add(new SetCardInfo("Healing Salve", 16, Rarity.COMMON, mage.cards.h.HealingSalve.class)); + cards.add(new SetCardInfo("Heat Ray", 199, Rarity.COMMON, mage.cards.h.HeatRay.class)); + cards.add(new SetCardInfo("Herald of Serra", 17, Rarity.RARE, mage.cards.h.HeraldOfSerra.class)); + cards.add(new SetCardInfo("Hermetic Study", 78, Rarity.COMMON, mage.cards.h.HermeticStudy.class)); + cards.add(new SetCardInfo("Hibernation", 79, Rarity.UNCOMMON, mage.cards.h.Hibernation.class)); + cards.add(new SetCardInfo("Hidden Ancients", 260, Rarity.UNCOMMON, mage.cards.h.HiddenAncients.class)); + cards.add(new SetCardInfo("Hidden Guerrillas", 261, Rarity.UNCOMMON, mage.cards.h.HiddenGuerrillas.class)); + cards.add(new SetCardInfo("Hidden Herd", 262, Rarity.RARE, mage.cards.h.HiddenHerd.class)); + cards.add(new SetCardInfo("Hidden Spider", 264, Rarity.COMMON, mage.cards.h.HiddenSpider.class)); + cards.add(new SetCardInfo("Hollow Dogs", 137, Rarity.COMMON, mage.cards.h.HollowDogs.class)); + cards.add(new SetCardInfo("Hopping Automaton", 297, Rarity.UNCOMMON, mage.cards.h.HoppingAutomaton.class)); + cards.add(new SetCardInfo("Horseshoe Crab", 80, Rarity.COMMON, mage.cards.h.HorseshoeCrab.class)); + cards.add(new SetCardInfo("Humble", 18, Rarity.UNCOMMON, mage.cards.h.Humble.class)); + cards.add(new SetCardInfo("Hush", 266, Rarity.COMMON, mage.cards.h.Hush.class)); + cards.add(new SetCardInfo("Ill-Gotten Gains", 138, Rarity.RARE, mage.cards.i.IllGottenGains.class)); + cards.add(new SetCardInfo("Imaginary Pet", 81, Rarity.RARE, mage.cards.i.ImaginaryPet.class)); + cards.add(new SetCardInfo("Intrepid Hero", 19, Rarity.RARE, mage.cards.i.IntrepidHero.class)); + cards.add(new SetCardInfo("Island", 335, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 336, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jagged Lightning", 200, Rarity.UNCOMMON, mage.cards.j.JaggedLightning.class)); + cards.add(new SetCardInfo("Karn, Silver Golem", 298, Rarity.RARE, mage.cards.k.KarnSilverGolem.class)); + cards.add(new SetCardInfo("Launch", 82, Rarity.COMMON, mage.cards.l.Launch.class)); + cards.add(new SetCardInfo("Lay Waste", 201, Rarity.COMMON, mage.cards.l.LayWaste.class)); + cards.add(new SetCardInfo("Lifeline", 299, Rarity.RARE, mage.cards.l.Lifeline.class)); + cards.add(new SetCardInfo("Lightning Dragon", 202, Rarity.RARE, mage.cards.l.LightningDragon.class)); + cards.add(new SetCardInfo("Lilting Refrain", 83, Rarity.UNCOMMON, mage.cards.l.LiltingRefrain.class)); + cards.add(new SetCardInfo("Lingering Mirage", 84, Rarity.UNCOMMON, mage.cards.l.LingeringMirage.class)); + cards.add(new SetCardInfo("Looming Shade", 139, Rarity.COMMON, mage.cards.l.LoomingShade.class)); + cards.add(new SetCardInfo("Lotus Blossom", 300, Rarity.RARE, mage.cards.l.LotusBlossom.class)); + cards.add(new SetCardInfo("Lull", 267, Rarity.COMMON, mage.cards.l.Lull.class)); + cards.add(new SetCardInfo("Lurking Evil", 140, Rarity.RARE, mage.cards.l.LurkingEvil.class)); + cards.add(new SetCardInfo("Mana Leech", 141, Rarity.UNCOMMON, mage.cards.m.ManaLeech.class)); + cards.add(new SetCardInfo("Meltdown", 203, Rarity.UNCOMMON, mage.cards.m.Meltdown.class)); + cards.add(new SetCardInfo("Metrognome", 301, Rarity.RARE, mage.cards.m.Metrognome.class)); + cards.add(new SetCardInfo("Midsummer Revel", 268, Rarity.RARE, mage.cards.m.MidsummerRevel.class)); + cards.add(new SetCardInfo("Mishra's Helix", 302, Rarity.RARE, mage.cards.m.MishrasHelix.class)); + cards.add(new SetCardInfo("Mobile Fort", 303, Rarity.UNCOMMON, mage.cards.m.MobileFort.class)); + cards.add(new SetCardInfo("Monk Idealist", 20, Rarity.UNCOMMON, mage.cards.m.MonkIdealist.class)); + cards.add(new SetCardInfo("Monk Realist", 21, Rarity.COMMON, mage.cards.m.MonkRealist.class)); + cards.add(new SetCardInfo("Morphling", 85, Rarity.RARE, mage.cards.m.Morphling.class)); + cards.add(new SetCardInfo("Mountain", 343, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 344, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 345, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("No Rest for the Wicked", 142, Rarity.UNCOMMON, mage.cards.n.NoRestForTheWicked.class)); + cards.add(new SetCardInfo("Noetic Scales", 304, Rarity.RARE, mage.cards.n.NoeticScales.class)); + cards.add(new SetCardInfo("Okk", 204, Rarity.RARE, mage.cards.o.Okk.class)); + cards.add(new SetCardInfo("Opal Acrolith", 22, Rarity.UNCOMMON, mage.cards.o.OpalAcrolith.class)); + cards.add(new SetCardInfo("Opal Archangel", 23, Rarity.RARE, mage.cards.o.OpalArchangel.class)); + cards.add(new SetCardInfo("Opal Caryatid", 24, Rarity.COMMON, mage.cards.o.OpalCaryatid.class)); + cards.add(new SetCardInfo("Opal Gargoyle", 25, Rarity.COMMON, mage.cards.o.OpalGargoyle.class)); + cards.add(new SetCardInfo("Opal Titan", 26, Rarity.RARE, mage.cards.o.OpalTitan.class)); + cards.add(new SetCardInfo("Oppression", 143, Rarity.RARE, mage.cards.o.Oppression.class)); + cards.add(new SetCardInfo("Order of Yawgmoth", 144, Rarity.UNCOMMON, mage.cards.o.OrderOfYawgmoth.class)); + cards.add(new SetCardInfo("Pacifism", 27, Rarity.COMMON, mage.cards.p.Pacifism.class)); + cards.add(new SetCardInfo("Parasitic Bond", 145, Rarity.UNCOMMON, mage.cards.p.ParasiticBond.class)); + cards.add(new SetCardInfo("Pariah", 28, Rarity.RARE, mage.cards.p.Pariah.class)); + cards.add(new SetCardInfo("Path of Peace", 29, Rarity.COMMON, mage.cards.p.PathOfPeace.class)); + cards.add(new SetCardInfo("Pegasus Charger", 30, Rarity.COMMON, mage.cards.p.PegasusCharger.class)); + cards.add(new SetCardInfo("Pendrell Drake", 86, Rarity.COMMON, mage.cards.p.PendrellDrake.class)); + cards.add(new SetCardInfo("Pendrell Flux", 87, Rarity.COMMON, mage.cards.p.PendrellFlux.class)); + cards.add(new SetCardInfo("Peregrine Drake", 88, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); + cards.add(new SetCardInfo("Persecute", 146, Rarity.RARE, mage.cards.p.Persecute.class)); + cards.add(new SetCardInfo("Pestilence", 147, Rarity.COMMON, mage.cards.p.Pestilence.class)); + cards.add(new SetCardInfo("Phyrexian Colossus", 305, Rarity.RARE, mage.cards.p.PhyrexianColossus.class)); + cards.add(new SetCardInfo("Phyrexian Ghoul", 148, Rarity.COMMON, mage.cards.p.PhyrexianGhoul.class)); + cards.add(new SetCardInfo("Phyrexian Processor", 306, Rarity.RARE, mage.cards.p.PhyrexianProcessor.class)); + cards.add(new SetCardInfo("Phyrexian Tower", 322, Rarity.RARE, mage.cards.p.PhyrexianTower.class)); + cards.add(new SetCardInfo("Pit Trap", 307, Rarity.UNCOMMON, mage.cards.p.PitTrap.class)); + cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Planar Birth", 31, Rarity.RARE, mage.cards.p.PlanarBirth.class)); + cards.add(new SetCardInfo("Planar Void", 149, Rarity.UNCOMMON, mage.cards.p.PlanarVoid.class)); + cards.add(new SetCardInfo("Polluted Mire", 323, Rarity.COMMON, mage.cards.p.PollutedMire.class)); + cards.add(new SetCardInfo("Pouncing Jaguar", 269, Rarity.COMMON, mage.cards.p.PouncingJaguar.class)); + cards.add(new SetCardInfo("Power Sink", 89, Rarity.COMMON, mage.cards.p.PowerSink.class)); + cards.add(new SetCardInfo("Presence of the Master", 32, Rarity.UNCOMMON, mage.cards.p.PresenceOfTheMaster.class)); + cards.add(new SetCardInfo("Priest of Gix", 150, Rarity.UNCOMMON, mage.cards.p.PriestOfGix.class)); + cards.add(new SetCardInfo("Priest of Titania", 270, Rarity.COMMON, mage.cards.p.PriestOfTitania.class)); + cards.add(new SetCardInfo("Purging Scythe", 308, Rarity.RARE, mage.cards.p.PurgingScythe.class)); + cards.add(new SetCardInfo("Rain of Filth", 151, Rarity.UNCOMMON, mage.cards.r.RainOfFilth.class)); + cards.add(new SetCardInfo("Rain of Salt", 206, Rarity.UNCOMMON, mage.cards.r.RainOfSalt.class)); + cards.add(new SetCardInfo("Ravenous Skirge", 152, Rarity.COMMON, mage.cards.r.RavenousSkirge.class)); + cards.add(new SetCardInfo("Raze", 207, Rarity.COMMON, mage.cards.r.Raze.class)); + cards.add(new SetCardInfo("Recantation", 91, Rarity.RARE, mage.cards.r.Recantation.class)); + cards.add(new SetCardInfo("Reclusive Wight", 153, Rarity.UNCOMMON, mage.cards.r.ReclusiveWight.class)); + cards.add(new SetCardInfo("Redeem", 33, Rarity.UNCOMMON, mage.cards.r.Redeem.class)); + cards.add(new SetCardInfo("Reflexes", 208, Rarity.COMMON, mage.cards.r.Reflexes.class)); + cards.add(new SetCardInfo("Rejuvenate", 271, Rarity.COMMON, mage.cards.r.Rejuvenate.class)); + cards.add(new SetCardInfo("Remembrance", 34, Rarity.RARE, mage.cards.r.Remembrance.class)); + cards.add(new SetCardInfo("Remote Isle", 324, Rarity.COMMON, mage.cards.r.RemoteIsle.class)); + cards.add(new SetCardInfo("Reprocess", 154, Rarity.RARE, mage.cards.r.Reprocess.class)); + cards.add(new SetCardInfo("Rescind", 92, Rarity.COMMON, mage.cards.r.Rescind.class)); + cards.add(new SetCardInfo("Retaliation", 272, Rarity.UNCOMMON, mage.cards.r.Retaliation.class)); + cards.add(new SetCardInfo("Retromancer", 209, Rarity.COMMON, mage.cards.r.Retromancer.class)); + cards.add(new SetCardInfo("Rewind", 93, Rarity.COMMON, mage.cards.r.Rewind.class)); + cards.add(new SetCardInfo("Rumbling Crescendo", 210, Rarity.RARE, mage.cards.r.RumblingCrescendo.class)); + cards.add(new SetCardInfo("Rune of Protection: Artifacts", 35, Rarity.UNCOMMON, mage.cards.r.RuneOfProtectionArtifacts.class)); + cards.add(new SetCardInfo("Rune of Protection: Black", 36, Rarity.COMMON, mage.cards.r.RuneOfProtectionBlack.class)); + cards.add(new SetCardInfo("Rune of Protection: Blue", 37, Rarity.COMMON, mage.cards.r.RuneOfProtectionBlue.class)); + cards.add(new SetCardInfo("Rune of Protection: Green", 38, Rarity.COMMON, mage.cards.r.RuneOfProtectionGreen.class)); + cards.add(new SetCardInfo("Rune of Protection: Lands", 39, Rarity.RARE, mage.cards.r.RuneOfProtectionLands.class)); + cards.add(new SetCardInfo("Rune of Protection: Red", 40, Rarity.COMMON, mage.cards.r.RuneOfProtectionRed.class)); + cards.add(new SetCardInfo("Rune of Protection: White", 41, Rarity.COMMON, mage.cards.r.RuneOfProtectionWhite.class)); + cards.add(new SetCardInfo("Sanctum Custodian", 42, Rarity.COMMON, mage.cards.s.SanctumCustodian.class)); + cards.add(new SetCardInfo("Sanctum Guardian", 43, Rarity.UNCOMMON, mage.cards.s.SanctumGuardian.class)); + cards.add(new SetCardInfo("Sandbar Merfolk", 94, Rarity.COMMON, mage.cards.s.SandbarMerfolk.class)); + cards.add(new SetCardInfo("Sandbar Serpent", 95, Rarity.UNCOMMON, mage.cards.s.SandbarSerpent.class)); + cards.add(new SetCardInfo("Sanguine Guard", 155, Rarity.UNCOMMON, mage.cards.s.SanguineGuard.class)); + cards.add(new SetCardInfo("Scald", 211, Rarity.UNCOMMON, mage.cards.s.Scald.class)); + cards.add(new SetCardInfo("Scoria Wurm", 212, Rarity.RARE, mage.cards.s.ScoriaWurm.class)); + cards.add(new SetCardInfo("Scrap", 213, Rarity.COMMON, mage.cards.s.Scrap.class)); + cards.add(new SetCardInfo("Seasoned Marshal", 44, Rarity.UNCOMMON, mage.cards.s.SeasonedMarshal.class)); + cards.add(new SetCardInfo("Serra Avatar", 45, Rarity.RARE, mage.cards.s.SerraAvatar.class)); + cards.add(new SetCardInfo("Serra's Embrace", 47, Rarity.UNCOMMON, mage.cards.s.SerrasEmbrace.class)); + cards.add(new SetCardInfo("Serra's Liturgy", 49, Rarity.RARE, mage.cards.s.SerrasLiturgy.class)); + cards.add(new SetCardInfo("Serra's Sanctum", 325, Rarity.RARE, mage.cards.s.SerrasSanctum.class)); + cards.add(new SetCardInfo("Serra Zealot", 46, Rarity.COMMON, mage.cards.s.SerraZealot.class)); + cards.add(new SetCardInfo("Shimmering Barrier", 50, Rarity.UNCOMMON, mage.cards.s.ShimmeringBarrier.class)); + cards.add(new SetCardInfo("Shivan Gorge", 326, Rarity.RARE, mage.cards.s.ShivanGorge.class)); + cards.add(new SetCardInfo("Shivan Hellkite", 214, Rarity.RARE, mage.cards.s.ShivanHellkite.class)); + cards.add(new SetCardInfo("Shivan Raptor", 215, Rarity.UNCOMMON, mage.cards.s.ShivanRaptor.class)); + cards.add(new SetCardInfo("Shiv's Embrace", 216, Rarity.UNCOMMON, mage.cards.s.ShivsEmbrace.class)); + cards.add(new SetCardInfo("Show and Tell", 96, Rarity.RARE, mage.cards.s.ShowAndTell.class)); + cards.add(new SetCardInfo("Shower of Sparks", 217, Rarity.COMMON, mage.cards.s.ShowerOfSparks.class)); + cards.add(new SetCardInfo("Sicken", 156, Rarity.COMMON, mage.cards.s.Sicken.class)); + cards.add(new SetCardInfo("Silent Attendant", 51, Rarity.COMMON, mage.cards.s.SilentAttendant.class)); + cards.add(new SetCardInfo("Skirge Familiar", 157, Rarity.UNCOMMON, mage.cards.s.SkirgeFamiliar.class)); + cards.add(new SetCardInfo("Skittering Skirge", 158, Rarity.COMMON, mage.cards.s.SkitteringSkirge.class)); + cards.add(new SetCardInfo("Sleeper Agent", 159, Rarity.RARE, mage.cards.s.SleeperAgent.class)); + cards.add(new SetCardInfo("Slippery Karst", 327, Rarity.COMMON, mage.cards.s.SlipperyKarst.class)); + cards.add(new SetCardInfo("Smokestack", 309, Rarity.RARE, mage.cards.s.Smokestack.class)); + cards.add(new SetCardInfo("Smoldering Crater", 328, Rarity.COMMON, mage.cards.s.SmolderingCrater.class)); + cards.add(new SetCardInfo("Sneak Attack", 218, Rarity.RARE, mage.cards.s.SneakAttack.class)); + cards.add(new SetCardInfo("Somnophore", 97, Rarity.RARE, mage.cards.s.Somnophore.class)); + cards.add(new SetCardInfo("Songstitcher", 52, Rarity.UNCOMMON, mage.cards.s.Songstitcher.class)); + cards.add(new SetCardInfo("Spined Fluke", 160, Rarity.UNCOMMON, mage.cards.s.SpinedFluke.class)); + cards.add(new SetCardInfo("Spire Owl", 98, Rarity.COMMON, mage.cards.s.SpireOwl.class)); + cards.add(new SetCardInfo("Sporogenesis", 273, Rarity.RARE, mage.cards.s.Sporogenesis.class)); + cards.add(new SetCardInfo("Spreading Algae", 274, Rarity.UNCOMMON, mage.cards.s.SpreadingAlgae.class)); + cards.add(new SetCardInfo("Steam Blast", 219, Rarity.UNCOMMON, mage.cards.s.SteamBlast.class)); + cards.add(new SetCardInfo("Stern Proctor", 99, Rarity.UNCOMMON, mage.cards.s.SternProctor.class)); + cards.add(new SetCardInfo("Stroke of Genius", 100, Rarity.RARE, mage.cards.s.StrokeOfGenius.class)); + cards.add(new SetCardInfo("Sulfuric Vapors", 220, Rarity.RARE, mage.cards.s.SulfuricVapors.class)); + cards.add(new SetCardInfo("Sunder", 101, Rarity.RARE, mage.cards.s.Sunder.class)); + cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 340, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 341, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 342, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Symbiosis", 275, Rarity.COMMON, mage.cards.s.Symbiosis.class)); + cards.add(new SetCardInfo("Tainted Aether", 161, Rarity.RARE, mage.cards.t.TaintedAether.class)); + cards.add(new SetCardInfo("Telepathy", 102, Rarity.UNCOMMON, mage.cards.t.Telepathy.class)); + cards.add(new SetCardInfo("Temporal Aperture", 310, Rarity.RARE, mage.cards.t.TemporalAperture.class)); + cards.add(new SetCardInfo("Thran Quarry", 329, Rarity.RARE, mage.cards.t.ThranQuarry.class)); + cards.add(new SetCardInfo("Thran Turbine", 311, Rarity.UNCOMMON, mage.cards.t.ThranTurbine.class)); + cards.add(new SetCardInfo("Thundering Giant", 221, Rarity.UNCOMMON, mage.cards.t.ThunderingGiant.class)); + cards.add(new SetCardInfo("Time Spiral", 103, Rarity.RARE, mage.cards.t.TimeSpiral.class)); + cards.add(new SetCardInfo("Titania's Boon", 276, Rarity.UNCOMMON, mage.cards.t.TitaniasBoon.class)); + cards.add(new SetCardInfo("Titania's Chosen", 277, Rarity.UNCOMMON, mage.cards.t.TitaniasChosen.class)); + cards.add(new SetCardInfo("Tolarian Academy", 330, Rarity.RARE, mage.cards.t.TolarianAcademy.class)); + cards.add(new SetCardInfo("Tolarian Winds", 104, Rarity.COMMON, mage.cards.t.TolarianWinds.class)); + cards.add(new SetCardInfo("Torch Song", 222, Rarity.UNCOMMON, mage.cards.t.TorchSong.class)); + cards.add(new SetCardInfo("Treefolk Seedlings", 278, Rarity.UNCOMMON, mage.cards.t.TreefolkSeedlings.class)); + cards.add(new SetCardInfo("Treetop Rangers", 279, Rarity.COMMON, mage.cards.t.TreetopRangers.class)); + cards.add(new SetCardInfo("Turnabout", 105, Rarity.UNCOMMON, mage.cards.t.Turnabout.class)); + cards.add(new SetCardInfo("Umbilicus", 312, Rarity.RARE, mage.cards.u.Umbilicus.class)); + cards.add(new SetCardInfo("Unnerve", 162, Rarity.COMMON, mage.cards.u.Unnerve.class)); + cards.add(new SetCardInfo("Unworthy Dead", 163, Rarity.COMMON, mage.cards.u.UnworthyDead.class)); + cards.add(new SetCardInfo("Urza's Armor", 313, Rarity.UNCOMMON, mage.cards.u.UrzasArmor.class)); + cards.add(new SetCardInfo("Vampiric Embrace", 164, Rarity.UNCOMMON, mage.cards.v.VampiricEmbrace.class)); + cards.add(new SetCardInfo("Vebulid", 165, Rarity.RARE, mage.cards.v.Vebulid.class)); + cards.add(new SetCardInfo("Vernal Bloom", 281, Rarity.RARE, mage.cards.v.VernalBloom.class)); + cards.add(new SetCardInfo("Viashino Outrider", 223, Rarity.COMMON, mage.cards.v.ViashinoOutrider.class)); + cards.add(new SetCardInfo("Viashino Runner", 224, Rarity.COMMON, mage.cards.v.ViashinoRunner.class)); + cards.add(new SetCardInfo("Viashino Sandswimmer", 225, Rarity.RARE, mage.cards.v.ViashinoSandswimmer.class)); + cards.add(new SetCardInfo("Viashino Weaponsmith", 226, Rarity.COMMON, mage.cards.v.ViashinoWeaponsmith.class)); + cards.add(new SetCardInfo("Victimize", 166, Rarity.UNCOMMON, mage.cards.v.Victimize.class)); + cards.add(new SetCardInfo("Vile Requiem", 167, Rarity.UNCOMMON, mage.cards.v.VileRequiem.class)); + cards.add(new SetCardInfo("Voice of Grace", 54, Rarity.UNCOMMON, mage.cards.v.VoiceOfGrace.class)); + cards.add(new SetCardInfo("Voice of Law", 55, Rarity.UNCOMMON, mage.cards.v.VoiceOfLaw.class)); + cards.add(new SetCardInfo("Voltaic Key", 314, Rarity.UNCOMMON, mage.cards.v.VoltaicKey.class)); + cards.add(new SetCardInfo("Vug Lizard", 227, Rarity.UNCOMMON, mage.cards.v.VugLizard.class)); + cards.add(new SetCardInfo("War Dance", 282, Rarity.UNCOMMON, mage.cards.w.WarDance.class)); + cards.add(new SetCardInfo("Wall of Junk", 315, Rarity.UNCOMMON, mage.cards.w.WallOfJunk.class)); + cards.add(new SetCardInfo("Waylay", 56, Rarity.UNCOMMON, mage.cards.w.Waylay.class)); + cards.add(new SetCardInfo("Western Paladin", 168, Rarity.RARE, mage.cards.w.WesternPaladin.class)); + cards.add(new SetCardInfo("Whetstone", 316, Rarity.RARE, mage.cards.w.Whetstone.class)); + cards.add(new SetCardInfo("Whirlwind", 283, Rarity.RARE, mage.cards.w.Whirlwind.class)); + cards.add(new SetCardInfo("Wild Dogs", 284, Rarity.COMMON, mage.cards.w.WildDogs.class)); + cards.add(new SetCardInfo("Wildfire", 228, Rarity.RARE, mage.cards.w.Wildfire.class)); + cards.add(new SetCardInfo("Windfall", 111, Rarity.UNCOMMON, mage.cards.w.Windfall.class)); + cards.add(new SetCardInfo("Winding Wurm", 285, Rarity.COMMON, mage.cards.w.WindingWurm.class)); + cards.add(new SetCardInfo("Wirecat", 317, Rarity.UNCOMMON, mage.cards.w.Wirecat.class)); + cards.add(new SetCardInfo("Witch Engine", 169, Rarity.RARE, mage.cards.w.WitchEngine.class)); + cards.add(new SetCardInfo("Wizard Mentor", 112, Rarity.COMMON, mage.cards.w.WizardMentor.class)); + cards.add(new SetCardInfo("Worn Powerstone", 318, Rarity.UNCOMMON, mage.cards.w.WornPowerstone.class)); + cards.add(new SetCardInfo("Worship", 57, Rarity.RARE, mage.cards.w.Worship.class)); + cards.add(new SetCardInfo("Yawgmoth's Edict", 170, Rarity.UNCOMMON, mage.cards.y.YawgmothsEdict.class)); + cards.add(new SetCardInfo("Yawgmoth's Will", 171, Rarity.RARE, mage.cards.y.YawgmothsWill.class)); + cards.add(new SetCardInfo("Zephid", 113, Rarity.RARE, mage.cards.z.Zephid.class)); + cards.add(new SetCardInfo("Zephid's Embrace", 114, Rarity.UNCOMMON, mage.cards.z.ZephidsEmbrace.class)); + } +} From 843702bd86210fb1b51ea65614563bfbf2ccc2de Mon Sep 17 00:00:00 2001 From: brodee Date: Fri, 26 Oct 2018 22:17:57 -0700 Subject: [PATCH 083/167] draftbots and afk autopicks will more aggressivly take rares two draft quality of life improvements for situations when real players quit or go afk. 1. made the draftbot lean on rarity for card ratings. this helps make the draftbots behave and not just pass bombs to the human players. 2. changed the draft autopick that happens when the timer runs out and the player hasn't selected anything. I changed it to pick the last card in the pack, which should be the rarest, so basically it raredrafts. again making it so AFK players aren't just feeding real live human players the best cards. --- .../java/mage/player/ai/utils/RateCard.java | 23 ++++++++++++++++++- .../main/java/mage/game/draft/DraftImpl.java | 3 ++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index 5197c33536..e737122a95 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -13,6 +13,7 @@ import org.apache.log4j.Logger; import java.io.InputStream; import java.util.*; +import mage.constants.Rarity; import mage.constants.SubType; /** @@ -71,7 +72,7 @@ public final class RateCard { type = 6; } int score = 10 * getCardRating(card) + 2 * type + getManaCostScore(card, allowedColors) - + 40 * isRemoval(card); + + 40 * isRemoval(card) + getRarityScore(card); if (allowedColors == null) rated.put(card.getName(), score); return score; @@ -218,6 +219,26 @@ public final class RateCard { return 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]/*-DOUBLE_PENALTY[doubleCount]*/); } + /** + * Get rarity score. + * nowadays, cards that are more rare are more powerful, lets + * trust that and play the shiny cards. + * + * @param card + * @return integer rating value + */ + private static int getRarityScore(Card card) { + Rarity r = card.getRarity(); + if (Rarity.MYTHIC == r){ + return 80; + }else if (Rarity.RARE == r){ + return 50; + }else if (Rarity.UNCOMMON == r){ + return 25; + }else{ + return 1; + } + } /** * Determines whether mana symbol is color. * diff --git a/Mage/src/main/java/mage/game/draft/DraftImpl.java b/Mage/src/main/java/mage/game/draft/DraftImpl.java index 35efc14431..5ef5a2330e 100644 --- a/Mage/src/main/java/mage/game/draft/DraftImpl.java +++ b/Mage/src/main/java/mage/game/draft/DraftImpl.java @@ -147,7 +147,8 @@ public abstract class DraftImpl implements Draft { @Override public void autoPick(UUID playerId) { - this.addPick(playerId, players.get(playerId).getBooster().get(0).getId(), null); + List booster = players.get(playerId).getBooster(); + this.addPick(playerId, booster.get(booster.size()-1).getId(), null); } protected void passLeft() { From 04457558b39f957a95444a187d10fe31b1fa491c Mon Sep 17 00:00:00 2001 From: brodee Date: Sat, 27 Oct 2018 11:50:59 -0700 Subject: [PATCH 084/167] ai tweaks: improve rating for multicolor cards and reduce effect of rarity multicolor cards are the payoffs for playing those colors so they should be better reduced the effect of rarity increasing the rating --- .../java/mage/player/ai/utils/RateCard.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index e737122a95..877bb46631 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -169,11 +169,13 @@ public final class RateCard { } private static final int SINGLE_PENALTY[] = {0, 1, 1, 3, 6, 9}; + private static final int MULTICOLOR_BONUS = 15; /** * Get manacost score. * Depends on chosen colors. Returns negative score for those cards that doesn't fit allowed colors. * If allowed colors are not chosen, then score based on converted cost is returned with penalty for heavy colored cards. + * gives bonus to multicolor cards that fit within allowed colors and if allowed colors is <5 * * * @param card @@ -216,7 +218,12 @@ public final class RateCard { } if (maxSingleCount > 5) maxSingleCount = 5; - return 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]/*-DOUBLE_PENALTY[doubleCount]*/); + + int rate = 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]); + if( singleCount.size() > 1 && singleCount.size() < 5){ + rate += MULTICOLOR_BONUS; + } + return rate; } /** @@ -230,13 +237,13 @@ public final class RateCard { private static int getRarityScore(Card card) { Rarity r = card.getRarity(); if (Rarity.MYTHIC == r){ - return 80; + return 60; }else if (Rarity.RARE == r){ - return 50; + return 40; }else if (Rarity.UNCOMMON == r){ - return 25; + return 20; }else{ - return 1; + return 0; } } /** From 1f31323f47b5d8f7fbabafc05b6e52300ff96e59 Mon Sep 17 00:00:00 2001 From: brodee Date: Sat, 27 Oct 2018 11:53:05 -0700 Subject: [PATCH 085/167] fixed bug in test that skipped manual targetting addtarget was being ignored and AI was being used to determine a target. the spell has a target so I think this is not a bug with add target but rather the test itself --- .../mage/test/cards/single/soi/PrizedAmalgamTest.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/PrizedAmalgamTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/PrizedAmalgamTest.java index 0cd8182c34..807859f205 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/PrizedAmalgamTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/soi/PrizedAmalgamTest.java @@ -26,8 +26,7 @@ public class PrizedAmalgamTest extends CardTestPlayerBase { addCard(Zone.GRAVEYARD, playerA, "Prized Amalgam", 1); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate"); - addTarget(playerA, "Bronze Sable"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate", "Bronze Sable"); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -72,8 +71,7 @@ public class PrizedAmalgamTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); addCard(Zone.GRAVEYARD, playerB, "Prized Amalgam", 1); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate"); - addTarget(playerA, "Hill Giant"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reanimate", "Hill Giant"); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -95,8 +93,7 @@ public class PrizedAmalgamTest extends CardTestPlayerBase { // Whenever a creature enters the battlefield, if it entered from your graveyard or you cast it from your graveyard, return Prized Amalgam from your graveyard to the battlefield tapped at the beginning of the next end step. addCard(Zone.GRAVEYARD, playerB, "Prized Amalgam", 1); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Necromantic Summons"); - addTarget(playerA, "Merfolk Looter"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Necromantic Summons", "Merfolk Looter"); setStopAt(1, PhaseStep.END_TURN); execute(); From bdf3394b848805e7375aaaaedc3962b2f495995e Mon Sep 17 00:00:00 2001 From: brodee Date: Sat, 27 Oct 2018 11:55:05 -0700 Subject: [PATCH 086/167] changed the card used in summoner's egg test this test uses ai to determine which card to imprint, with my other changes to AI, the rarity of the cards changed the relative rating of these two cards. I changed the merfolk to be a common merfolk so that part of the card rating shouldn't affect it --- .../mage/test/cards/facedown/SummonersEggTest.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java index e9354e7a8d..ab984d69d8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java @@ -27,17 +27,16 @@ public class SummonersEggTest extends CardTestPlayerBase { @Test public void testSummonersEggImprint() { addCard(Zone.HAND, playerA, "Summoner's Egg"); - addCard(Zone.HAND, playerA, "Sejiri Merfolk"); + addCard(Zone.HAND, playerA, "Maritime Guard"); addCard(Zone.HAND, playerA, "Goblin Roughrider"); addCard(Zone.BATTLEFIELD, playerA, "Island", 4); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summoner's Egg"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summoner's Egg"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - + assertHandCount(playerA, 1); - assertHandCount(playerA, "Sejiri Merfolk", 1); + assertHandCount(playerA, "Maritime Guard", 1); assertHandCount(playerA, "Goblin Roughrider", 0); assertExileCount("Goblin Roughrider", 1); @@ -53,7 +52,7 @@ public class SummonersEggTest extends CardTestPlayerBase { @Test public void testSummonersEggDies() { addCard(Zone.HAND, playerA, "Summoner's Egg"); - addCard(Zone.HAND, playerA, "Sejiri Merfolk"); + addCard(Zone.HAND, playerA, "Maritime Guard"); addCard(Zone.HAND, playerA, "Goblin Roughrider"); addCard(Zone.BATTLEFIELD, playerA, "Island", 4); addCard(Zone.HAND, playerB, "Char"); @@ -67,7 +66,7 @@ public class SummonersEggTest extends CardTestPlayerBase { execute(); assertHandCount(playerA, 1); - assertHandCount(playerA, "Sejiri Merfolk", 1); + assertHandCount(playerA, "Maritime Guard", 1); assertHandCount(playerA, "Goblin Roughrider", 0); assertGraveyardCount(playerA, "Summoner's Egg", 1); From 4f61afa62b5cd332ec5408b36cd24408483388b8 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 28 Oct 2018 00:16:14 -0700 Subject: [PATCH 087/167] AI updates, more cards will have the isRemoval bonus to their card rating these weren't being picked up as removal spells and now are: * modal spells where one mode is a removal spell * spells that do a dynamic amount of damage, such as fireball * cards that reduce the toughness temporarily or permanently * cards that keep a creature tapped down * cards that exile a creature * cards that damage creatures that are attacking or blocking * enchantments that exile a creature when they etb * fight cards, and one sided fight cards the ai will now rate those types of cards higher as they are removal --- .../java/mage/player/ai/utils/RateCard.java | 88 +++++++++++++------ Mage.Sets/src/mage/cards/j/JusticeStrike.java | 2 +- ...InControllersUntapStepEnchantedEffect.java | 2 +- ...xileAndGainLifeEqualPowerTargetEffect.java | 2 +- .../common/ExileUntilSourceLeavesEffect.java | 2 +- .../combat/CantAttackBlockAttachedEffect.java | 3 +- 6 files changed, 69 insertions(+), 30 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index 877bb46631..35d7c3bbeb 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -7,14 +7,25 @@ import mage.cards.Card; import mage.constants.ColoredManaSymbol; import mage.constants.Outcome; import mage.target.Target; -import mage.target.common.TargetAnyTarget; import mage.target.common.TargetCreaturePermanent; import org.apache.log4j.Logger; import java.io.InputStream; import java.util.*; +import mage.abilities.Mode; +import mage.abilities.effects.common.DamageWithPowerTargetEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.constants.Rarity; import mage.constants.SubType; +import mage.target.TargetPermanent; +import mage.target.common.TargetAttackingCreature; +import mage.target.common.TargetAttackingOrBlockingCreature; +import mage.target.common.TargetPlayerOrPlaneswalker; /** * Class responsible for reading ratings from resources and rating given cards. @@ -54,7 +65,6 @@ public final class RateCard { public static int rateCard(Card card, List allowedColors) { if (allowedColors == null && rated.containsKey(card.getName())) { int rate = rated.get(card.getName()); -// log.info(card.getName() + " rate: " + rate); return rate; } int type; @@ -79,40 +89,68 @@ public final class RateCard { } private static int isRemoval(Card card) { - if (card.getSubtype(null).contains(SubType.AURA) || card.isInstant() || card.isSorcery()) { + if (card.isEnchantment() || card.isInstant() || card.isSorcery()) { for (Ability ability : card.getAbilities()) { - for (Effect effect : ability.getEffects()) { - if (effect.getOutcome() == Outcome.Removal) { - log.debug("Found removal: " + card.getName()); + for (Effect effect : ability.getEffects()) { + if (isEffectRemoval(card, ability, effect) == 1){ return 1; } - if (effect.getOutcome() == Outcome.Damage) { - if (effect instanceof DamageTargetEffect) { - DamageTargetEffect damageEffect = (DamageTargetEffect) effect; - if (damageEffect.getAmount() > 1) { - for (Target target : ability.getTargets()) { - if (target instanceof TargetCreaturePermanent || target instanceof TargetAnyTarget) { - log.debug("Found damage dealer: " + card.getName()); - return 1; - } - } - } - } - } - if (effect.getOutcome() == Outcome.DestroyPermanent) { - for (Target target : ability.getTargets()) { - if (target instanceof TargetCreaturePermanent) { - log.debug("Found destroyer: " + card.getName()); - return 1; - } + } + for (Mode mode: ability.getModes().values() ){ + for (Effect effect: mode.getEffects()){ + if (isEffectRemoval(card, ability, effect) == 1){ + return 1; } } } } + } return 0; } + + private static int isEffectRemoval(Card card, Ability ability, Effect effect){ + if (effect.getOutcome() == Outcome.Removal) { + log.debug("Found removal: " + card.getName()); + return 1; + } + //static List removalEffects =[BoostTargetEffect,BoostEnchantedEffect] + if (effect instanceof BoostTargetEffect || effect instanceof BoostEnchantedEffect){ + String text = effect.getText(null); + if (text.contains("/-")){ + // toughness reducer, aka removal + return 1; + } + } + if (effect instanceof FightTargetsEffect || effect instanceof DamageWithPowerTargetEffect){ + return 1; + } + if (effect.getOutcome() == Outcome.Damage || effect instanceof DamageTargetEffect) { + for (Target target : ability.getTargets()) { + if (!(target instanceof TargetPlayerOrPlaneswalker)){ + log.debug("Found damage dealer: " + card.getName()); + return 1; + } + } + } + if (effect.getOutcome() == Outcome.DestroyPermanent || + effect instanceof DestroyTargetEffect || + effect instanceof ExileTargetEffect || + effect instanceof ExileUntilSourceLeavesEffect) { + for (Target target : ability.getTargets()) { + if (target instanceof TargetCreaturePermanent || + target instanceof TargetAttackingCreature || + target instanceof TargetAttackingOrBlockingCreature || + target instanceof TargetPermanent) { + log.debug("Found destroyer/exiler: " + card.getName()); + return 1; + } + } + } + + return 0; + } /** * Return rating of the card. diff --git a/Mage.Sets/src/mage/cards/j/JusticeStrike.java b/Mage.Sets/src/mage/cards/j/JusticeStrike.java index db01871ddb..740a5b39cf 100644 --- a/Mage.Sets/src/mage/cards/j/JusticeStrike.java +++ b/Mage.Sets/src/mage/cards/j/JusticeStrike.java @@ -38,7 +38,7 @@ public final class JusticeStrike extends CardImpl { class JusticeStrikeEffect extends OneShotEffect { public JusticeStrikeEffect() { - super(Outcome.Benefit); + super(Outcome.Removal); this.staticText = "Target creature deals damage to itself equal to its power."; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java index 9371f56249..c0e7b28f54 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java @@ -19,7 +19,7 @@ public class DontUntapInControllersUntapStepEnchantedEffect extends ContinuousRu } public DontUntapInControllersUntapStepEnchantedEffect(String description) { - super(Duration.WhileOnBattlefield, Outcome.Detriment, false, true); + super(Duration.WhileOnBattlefield, Outcome.Removal, false, true); staticText = "Enchanted " + description + " doesn't untap during its controller's untap step"; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAndGainLifeEqualPowerTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAndGainLifeEqualPowerTargetEffect.java index 8126896e21..efa3ecd82d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAndGainLifeEqualPowerTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAndGainLifeEqualPowerTargetEffect.java @@ -14,7 +14,7 @@ import mage.players.Player; public class ExileAndGainLifeEqualPowerTargetEffect extends OneShotEffect { public ExileAndGainLifeEqualPowerTargetEffect() { - super(Outcome.GainLife); + super(Outcome.Removal); staticText = "Exile target creature. Its controller gains life equal to its power"; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileUntilSourceLeavesEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileUntilSourceLeavesEffect.java index 496096af91..bd54104237 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileUntilSourceLeavesEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileUntilSourceLeavesEffect.java @@ -19,7 +19,7 @@ import mage.util.CardUtil; public class ExileUntilSourceLeavesEffect extends OneShotEffect { public ExileUntilSourceLeavesEffect(String targetName) { - super(Outcome.Benefit); + super(Outcome.Removal); this.staticText = "exile target " + targetName + " an opponent controls until {this} leaves the battlefield"; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAttachedEffect.java index 082c2a9632..9a026d3a93 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAttachedEffect.java @@ -5,6 +5,7 @@ import mage.constants.AttachmentType; import mage.constants.Duration; import mage.abilities.Ability; import mage.abilities.effects.RestrictionEffect; +import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; @@ -14,7 +15,7 @@ import mage.game.permanent.Permanent; public class CantAttackBlockAttachedEffect extends RestrictionEffect { public CantAttackBlockAttachedEffect(AttachmentType attachmentType) { - super(Duration.WhileOnBattlefield); + super(Duration.WhileOnBattlefield, Outcome.Removal); this.staticText = attachmentType.verb() + " creature can't attack or block"; } From 893fd5dfc9d632cc2b29d2048493c429f13a0114 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 28 Oct 2018 00:33:47 -0700 Subject: [PATCH 088/167] correct justice strike outcome removal to damage --- Mage.Sets/src/mage/cards/j/JusticeStrike.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/j/JusticeStrike.java b/Mage.Sets/src/mage/cards/j/JusticeStrike.java index 740a5b39cf..f992cd7c4a 100644 --- a/Mage.Sets/src/mage/cards/j/JusticeStrike.java +++ b/Mage.Sets/src/mage/cards/j/JusticeStrike.java @@ -38,7 +38,7 @@ public final class JusticeStrike extends CardImpl { class JusticeStrikeEffect extends OneShotEffect { public JusticeStrikeEffect() { - super(Outcome.Removal); + super(Outcome.Damage); this.staticText = "Target creature deals damage to itself equal to its power."; } From 505a4b00a79971ced2c310173d05784d1a3900c4 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 28 Oct 2018 12:10:00 -0700 Subject: [PATCH 089/167] AI Draftbot rating system reworked, ratings added for 10 sets the way stored ratings for cards has been reworked 1. each set has its own ratings file and it will be loaded dynamically if the AI needs it 2. each ratings file for a set is normalized within itself, so the rating systems don't need to be scaled to match eachother. essentially cards are rated within the context of their set 3. changed the rarity rating booster to only apply to unrated cards 4. the file setsWithRatings.csv explains how to add additional ratings. no code changes are required, but a recompilation will be required to add the files to the jar. --- .../java/mage/player/ai/ComputerPlayer.java | 4 +- .../java/mage/player/ai/utils/RateCard.java | 92 ++++--- .../Mage.Player.AI/src/main/resources/aer.csv | 184 +++++++++++++ .../Mage.Player.AI/src/main/resources/akh.csv | 249 +++++++++++++++++ .../Mage.Player.AI/src/main/resources/dom.csv | 249 +++++++++++++++++ .../Mage.Player.AI/src/main/resources/grn.csv | 259 +++++++++++++++++ .../Mage.Player.AI/src/main/resources/hou.csv | 184 +++++++++++++ .../Mage.Player.AI/src/main/resources/ima.csv | 249 +++++++++++++++++ .../Mage.Player.AI/src/main/resources/kld.csv | 184 +++++++++++++ .../Mage.Player.AI/src/main/resources/m19.csv | 260 ++++++++++++++++++ .../Mage.Player.AI/src/main/resources/mm3.csv | 249 +++++++++++++++++ .../Mage.Player.AI/src/main/resources/rix.csv | 191 +++++++++++++ .../src/main/resources/setsWithRatings.csv | 19 ++ .../Mage.Player.AI/src/main/resources/xln.csv | 259 +++++++++++++++++ 14 files changed, 2591 insertions(+), 41 deletions(-) create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/aer.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/akh.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/dom.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/grn.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/hou.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ima.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/kld.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/m19.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/mm3.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/rix.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/setsWithRatings.csv create mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/xln.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 8362963995..4ebe78b127 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -2074,14 +2074,14 @@ public class ComputerPlayer extends PlayerImpl implements Player { int maxScore = RateCard.rateCard(bestCard, chosenColors); int pickedCardRate = RateCard.getCardRating(bestCard); - if (pickedCardRate <= 3) { + if (pickedCardRate <= 30) { // if card is bad // try to counter pick without any color restriction Card counterPick = pickBestCard(cards, null); int counterPickScore = RateCard.getCardRating(counterPick); // card is really good // take it! - if (counterPickScore >= 8) { + if (counterPickScore >= 80) { bestCard = counterPick; maxScore = RateCard.rateCard(bestCard, chosenColors); } diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index 35d7c3bbeb..4d488be4c9 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -36,14 +36,19 @@ import mage.target.common.TargetPlayerOrPlaneswalker; public final class RateCard { private static Map ratings; + private static List setsWithRatingsToBeLoaded; private static final Map rated = new HashMap<>(); - private static Integer min = Integer.MAX_VALUE, max = 0; /** * Rating that is given for new cards. * Ratings are in [1,10] range, so setting it high will make new cards appear more often. + * nowadays, cards that are more rare are more powerful, lets trust that and play the shiny cards. + * */ - private static final int DEFAULT_NOT_RATED_CARD_RATING = 4; + private static final int DEFAULT_NOT_RATED_CARD_RATING = 40; + private static final int DEFAULT_NOT_RATED_UNCOMMON_RATING = 60; + private static final int DEFAULT_NOT_RATED_RARE_RATING = 75; + private static final int DEFAULT_NOT_RATED_MYTHIC_RATING = 90; private static final Logger log = Logger.getLogger(RateCard.class); @@ -81,8 +86,8 @@ public final class RateCard { } else { type = 6; } - int score = 10 * getCardRating(card) + 2 * type + getManaCostScore(card, allowedColors) - + 40 * isRemoval(card) + getRarityScore(card); + int score = getCardRating(card) + 2 * type + getManaCostScore(card, allowedColors) + + 40 * isRemoval(card); if (allowedColors == null) rated.put(card.getName(), score); return score; @@ -148,7 +153,6 @@ public final class RateCard { } } } - return 0; } @@ -156,17 +160,36 @@ public final class RateCard { * Return rating of the card. * * @param card Card to rate. - * @return Rating number from [1;10]. + * @return Rating number from [1:100]. */ public static int getCardRating(Card card) { - if (ratings == null) { - readRatings(); + if (setsWithRatingsToBeLoaded == null){ + setsWithRatingsToBeLoaded = new LinkedList<>(); + InputStream is = RateCard.class.getResourceAsStream("/setsWithRatings.csv"); + Scanner scanner = new Scanner(is); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (line.substring(0,1) != "#"){ + setsWithRatingsToBeLoaded.add(line); + } + } } - if (ratings.containsKey(card.getName())) { - int r = ratings.get(card.getName()); - // normalize to [1..10] - float f = 10.0f * (r - min) / (max - min); - return (int) Math.round(f); + String exp = card.getExpansionSetCode().toLowerCase(); + readRatings(exp); + + if (ratings != null && ratings.containsKey(card.getName())) { + return ratings.get(card.getName()); + } + + Rarity r = card.getRarity(); + if (Rarity.COMMON == r){ + return DEFAULT_NOT_RATED_CARD_RATING; + }else if (Rarity.UNCOMMON == r){ + return DEFAULT_NOT_RATED_UNCOMMON_RATING; + }else if (Rarity.RARE == r){ + return DEFAULT_NOT_RATED_RARE_RATING; + }else if (Rarity.MYTHIC == r){ + return DEFAULT_NOT_RATED_MYTHIC_RATING; } return DEFAULT_NOT_RATED_CARD_RATING; } @@ -174,14 +197,20 @@ public final class RateCard { /** * Reads ratings from resources. */ - private synchronized static void readRatings() { + private synchronized static void readRatings(String expCode) { if (ratings == null) { ratings = new HashMap<>(); - readFromFile("/m13.csv"); + } + if (setsWithRatingsToBeLoaded.contains(expCode)){ + System.out.println("reading draftbot ratings for the set" + expCode); + readFromFile("/" + expCode + ".csv"); + setsWithRatingsToBeLoaded.remove(expCode); } } - + private static void readFromFile(String path) { + Integer min = Integer.MAX_VALUE, max = 0; + Map thisFileRatings = new HashMap<>(); try { InputStream is = RateCard.class.getResourceAsStream(path); Scanner scanner = new Scanner(is); @@ -197,12 +226,17 @@ public final class RateCard { if (rating < min) { min = rating; } - ratings.put(name, rating); + thisFileRatings.put(name, rating); } } + // normalize for the file to [1..100] + for (String name: thisFileRatings.keySet()){ + int r = thisFileRatings.get(name); + int newrating = (int)(100.0f * (r - min) / (max - min)); + ratings.put(name, newrating); + } } catch (Exception e) { e.printStackTrace(); - ratings.clear(); // no rating available on exception } } @@ -263,27 +297,7 @@ public final class RateCard { } return rate; } - - /** - * Get rarity score. - * nowadays, cards that are more rare are more powerful, lets - * trust that and play the shiny cards. - * - * @param card - * @return integer rating value - */ - private static int getRarityScore(Card card) { - Rarity r = card.getRarity(); - if (Rarity.MYTHIC == r){ - return 60; - }else if (Rarity.RARE == r){ - return 40; - }else if (Rarity.UNCOMMON == r){ - return 20; - }else{ - return 0; - } - } + /** * Determines whether mana symbol is color. * diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/aer.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/aer.csv new file mode 100644 index 0000000000..d586ce8d8c --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/aer.csv @@ -0,0 +1,184 @@ +Ajani Unyielding:40114 +Herald of Anguish:39905 +Rishkar, Peema Renegade:39137 +Aethersphere Harvester:38827 +Heart of Kiran:37403 +Yahenni’s Expertise:37199 +Tezzeret the Schemer:34694 +Solemn Recruit:34338 +Untethered Express:33419 +Battle at the Bridge:33072 +Yahenni, Undying Partisan:32377 +Fatal Push:32126 +Sram’s Expertise:32076 +Walking Ballista:31052 +Baral’s Expertise:30879 +Freejam Regent:30870 +Glint-Sleeve Siphoner:30022 +Ridgescale Tusker:30018 +Quicksmith Spy:29214 +Scrapper Champion:29176 +Aethertide Whale:28976 +Daring Demolition:28538 +Gifted Aetherborn:28163 +Quicksmith Rebel:27792 +Hungry Flames:27737 +Thopter Arrest:27574 +Exquisite Archangel:27415 +Kari Zev, Skyship Raider:27188 +Aetherwind Basker:26371 +Treasure Keeper:26283 +Greenbelt Rampager:26185 +Vengeful Rebel:25902 +Aethergeode Miner:25711 +Rishkar’s Expertise:25327 +Lightning Runner:25297 +Shock:25129 +Caught in the Brights:24815 +Lifecrafter’s Bestiary:24466 +Midnight Entourage:23732 +Sram, Senior Edificer:23386 +Metallic Mimic:23383 +Maulfist Revolutionary:23093 +Greenwheel Liberator:21817 +Chandra’s Revolution:21713 +Maverick Thopterist:21685 +Airdrop Aeronauts:21061 +Narnam Renegade:20406 +Winding Constrictor:20174 +Scrap Trawler:20001 +Monstrous Onslaught:19528 +Wind-Kin Raiders:19507 +Deadeye Harpooner:19305 +Skyship Plunderer:18967 +Aether Poisoner:18617 +Cruel Finality:18352 +Release the Gremlins:18286 +Aether Chaser:17813 +Rogue Refiner:17646 +Reckless Racer:17299 +Dawnfeather Eagle:17238 +Felidar Guardian:17122 +Prey Upon:16986 +Spire Patrol:16942 +Druid of the Cowl:16941 +Aetherstream Leopard:16826 +Reverse Engineer:15858 +Daredevil Dragster:15795 +Shielded Aether Thief:15596 +Scrounging Bandar:14827 +Lifecraft Cavalry:14821 +Pacification Array:14672 +Renegade Rallier:14442 +Trophy Mage:14084 +Enraged Giant:13989 +Foundry Hornet:13907 +Call for Unity:13832 +Renegade Wheelsmith:13717 +Peacewalker Colossus:13604 +Sweatworks Brawler:13229 +Aether Swooper:13171 +Outland Boar:13074 +Restoration Specialist:12713 +Perilous Predicament:12702 +Aeronaut Admiral:12409 +Tezzeret’s Touch:12281 +Oath of Ajani:11663 +Bastion Inventor:11485 +Weldfast Engineer:11309 +Countless Gears Renegade:11144 +Mechanized Production:10887 +Hinterland Drake:10667 +Consulate Crackdown:10549 +Renegade Map:10115 +Peema Aether-Seer:9906 +Unbridled Growth:9661 +Lifecraft Awakening:9620 +Baral, Chief of Compliance:9382 +Merchant’s Dockhand:9033 +Barricade Breaker:8635 +Lifecrafter’s Gift:8248 +Hidden Herbalists:8012 +Mobile Garrison:7976 +Aether Herder:7964 +Disallow:7550 +Kari Zev’s Expertise:7472 +Cogwork Assembler:7463 +Heroic Intervention:6922 +Hidden Stockpile:6732 +Illusionist’s Stratagem:6678 +Leave in the Dust:6675 +Ghirapur Osprey:6597 +Decommission:6354 +Ice Over:6297 +Night Market Aeronaut:6198 +Gremlin Infestation:6195 +Spire of Industry:6181 +Audacious Infiltrator:6084 +Sly Requisitioner:5718 +Alley Strangler:5595 +Silkweaver Elite:5574 +Aid from the Cowl:5463 +Highspire Infusion:5402 +Frontline Rebel:5350 +Invigorated Rampage:5268 +Defiant Salvager:5211 +Watchful Automaton:5147 +Siege Modification:5142 +Inspiring Statuary:4932 +Embraal Gear-Smasher:4847 +Deft Dismissal:4727 +Shipwreck Moray:4645 +Metallic Rebuke:4618 +Dispersal Technician:4389 +Resourceful Return:4325 +Efficient Construction:4108 +Welder Automaton:4076 +Aether Inspector:3989 +Ravenous Intruder:3963 +Ironclad Revolutionary:3930 +Implement of Ferocity:3720 +Alley Evasion:3712 +Hope of Ghirapur:3699 +Aerial Modification:3671 +Gonti’s Aether Heart:3295 +Foundry Assembler:3292 +Fen Hauler:3265 +Natural Obsolescence:3262 +Destructive Tampering:3239 +Implement of Examination:3217 +Irontread Crusher:3097 +Filigree Crawler:3020 +Servo Schematic:3006 +Verdant Automaton:2979 +Reservoir Walker:2918 +Whir of Invention:2916 +Paradox Engine:2714 +Salvage Scuttler:2677 +Augmenting Automaton:2636 +Fourth Bridge Prowler:2448 +Conviction:2411 +Lathnu Sailback:2352 +Planar Bridge:2348 +Night Market Guard:2244 +Bastion Enforcer:2236 +Precise Strike:2179 +Universal Solvent:2128 +Implement of Malice:2089 +Crackdown Construct:1926 +Dark Intimations:1876 +Pia’s Revolution:1850 +Renegade’s Getaway:1472 +Aegis Automaton:1355 +Consulate Dreadnought:1255 +Indomitable Creativity:1206 +Negate:1016 +Consulate Turret:1014 +Implement of Combustion:806 +Take into Custody:678 +Implement of Improvement:624 +Wrangle:543 +Ornithopter:177 +Gonti’s Machinations:167 +Prizefighter Construct:123 +184 Secret Salvage 77 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/akh.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/akh.csv new file mode 100644 index 0000000000..aa35d0b68e --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/akh.csv @@ -0,0 +1,249 @@ +Angel of Sanctions:1638 +Glorybringer:1590 +Oketra the True:1512 +Rhonas the Indomitable:1456 +Gideon of the Trials:1445 +Hazoret the Fervent:1404 +Liliana, Death’s Majesty:1370 +Archfiend of Ifnir:1346 +Cast Out:1331 +Curator of Mysteries:1329 +Regal Caracal:1324 +Glyph Keeper:1312 +Cut /// Ribbons:1310 +Dusk /// Dawn:1266 +Vizier of Many Faces:1252 +Never /// Return:1251 +Vizier of the Menagerie:1243 +Heart-Piercer Manticore:1220 +Liliana’s Mastery:1216 +Trial of Zeal:1195 +Samut, Voice of Dissent:1190 +Nissa, Steward of Elements:1174 +Magma Spray:1157 +Honored Hydra:1132 +Sweltering Suns:1126 +Glory-Bound Initiate:1125 +Lord of the Accursed:1119 +Ahn-Crop Crasher:1115 +Insult /// Injury:1113 +Champion of Rhonas:1096 +Plague Belcher:1095 +Angler Drake:1091 +Cartouche of Strength:1089 +Electrify:1083 +Combat Celebrant:1079 +Compulsory Rest:1073 +Crocodile of the Crossing:1061 +Gust Walker:1058 +Scaled Behemoth:1055 +Decimator Beetle:1050 +Bone Picker:1048 +Drake Haven:1042 +Mouth /// Feed:1039 +Channeler Initiate:1038 +Deem Worthy:1031 +Bontu the Glorified:1022 +Trial of Solidarity:1018 +Final Reward:1013 +Stir the Sands:1010 +Hapatra, Vizier of Poisons:1009 +Start /// Finish:1005 +Trial of Strength:1002 +Emberhorn Minotaur:999 +Prepare /// Fight:998 +Baleful Ammit:997 +Cartouche of Knowledge:989 +Cruel Reality:989 +Sandwurm Convergence:973 +Prowling Serpopard:965 +Trial of Ambition:962 +Devoted Crop-Mate:959 +Oketra’s Attendant:955 +Commit /// Memory:952 +Neheb, the Worthy:952 +Aven Wind Guide:944 +Bloodrage Brawler:944 +Fan Bearer:936 +Dread Wanderer:930 +Temmet, Vizier of Naktamun:924 +Oketra’s Monument:921 +Edifice of Authority:919 +Cartouche of Ambition:918 +Wayward Servant:905 +Lay Claim:903 +Splendid Agony:896 +Tah-Crop Elite:894 +Kefnet the Mindful:884 +Gravedigger:871 +Harsh Mentor:864 +Soulstinger:863 +Exemplar of Strength:862 +Cartouche of Zeal:861 +Defiant Greatmaw:846 +Enigma Drake:846 +Cartouche of Solidarity:840 +Labyrinth Guardian:836 +Vizier of Deferment:835 +Naga Vitalist:834 +Pull from Tomorrow:832 +Rags /// Riches:832 +Khenra Charioteer:829 +Hooded Brawler:828 +Horror of the Broken Lands:815 +Trueheart Duelist:815 +Honored Crop-Captain:813 +Bitterblade Warrior:812 +Shefet Monitor:808 +Heaven /// Earth:807 +Seraph of the Suns:805 +Nef-Crop Entangler:803 +Greater Sandwurm:802 +Ruthless Sniper:799 +Cursed Minotaur:798 +Rhet-Crop Spearmaster:796 +Soul-Scar Mage:796 +Trial of Knowledge:787 +Trueheart Twins:785 +Battlefield Scavenger:784 +Aven Initiate:782 +Wasteland Scorpion:778 +Impeccable Timing:774 +Essence Scatter:773 +Open into Wonder:769 +Unwavering Initiate:767 +Warfire Javelineer:765 +Manticore of the Gauntlet:762 +Binding Mummy:760 +Approach of the Second Sun:758 +Ahn-Crop Champion:757 +Synchronized Strike:756 +Winged Shepherd:747 +Ornery Kudu:742 +Cryptic Serpent:741 +Shimmerscale Drake:739 +Hieroglyphic Illumination:737 +Censor:733 +Illusory Wrappings:731 +Watchful Naga:731 +Vizier of Tumbling Sands:724 +Minotaur Sureshot:720 +Rhonas’s Monument:719 +Galestrike:718 +Merciless Javelineer:718 +Bounty of the Luxa:712 +Aven Mindcensor:708 +Naga Oracle:705 +Thresher Lizard:692 +Quarry Hauler:689 +Irrigated Farmland:688 +Pathmaker Initiate:681 +Shadowstorm Vizier:678 +Grim Strider:676 +Flameblade Adept:674 +Sheltered Thicket:672 +Destined /// Lead:668 +Wander in Death:668 +Weaver of Currents:663 +Blighted Bat:651 +Nest of Scarabs:648 +Oracle’s Vault:646 +Canyon Slough:643 +Evolving Wilds:640 +Colossapede:638 +Sacred Cat:637 +Doomed Dissenter:635 +Fetid Pools:628 +Festering Mummy:616 +Onward /// Victory:615 +Throne of the God-Pharaoh:613 +Anointed Procession:608 +Gift of Paradise:602 +Anointer Priest:599 +Consuming Fervor:595 +Limits of Solidarity:594 +Spring /// Mind:593 +Desert Cerodon:592 +Sparring Mummy:592 +River Serpent:584 +Seeker of Insight:582 +Shed Weakness:582 +Gideon’s Intervention:580 +Slither Blade:580 +Tah-Crop Skirmisher:580 +Initiate’s Companion:570 +Pitiless Vizier:567 +Scattered Groves:563 +Supernatural Stamina:563 +Vizier of Remedies:563 +Hekma Sentinels:562 +Bloodlust Inciter:559 +Pouncing Cheetah:559 +Winds of Rebuke:550 +Cancel:540 +Painful Lesson:536 +Mighty Leap:535 +Pyramid of the Pantheon:535 +Reduce /// Rubble:533 +Brute Strength:530 +Floodwaters:530 +Faith of the Devoted:529 +Manglehorn:529 +Miasmic Mummy:522 +Fling:519 +Oashra Cultivator:512 +In Oketra’s Name:510 +Forsake the Worldly:506 +Supply Caravan:505 +Time to Reflect:505 +Decision Paralysis:504 +Giant Spider:504 +Hapatra’s Mark:500 +Nimble-Blade Khenra:499 +Harvest Season:497 +Failure /// Comply:496 +Zenith Seeker:494 +Those Who Serve:491 +Bontu’s Monument:488 +As Foretold:487 +Tormenting Voice:487 +Hazoret’s Monument:485 +New Perspectives:484 +Pursue Glory:478 +Unburden:476 +Djeru’s Resolve:469 +Spidery Grasp:468 +Kefnet’s Monument:466 +Lay Bare the Heart:464 +Scribe of the Mindful:463 +Honed Khopesh:450 +Stinging Shot:443 +Trespasser’s Curse:431 +Blazing Volley:430 +Watchers of the Dead:415 +Sixth Sense:413 +Dune Beetle:386 +Cradle of the Accursed:382 +Glorious End:380 +Sacred Excavation:379 +Grasping Dunes:372 +Shadow of the Grave:370 +Cascading Cataracts:357 +Hyena Pack:356 +Benefaction of Rhonas:354 +Dissenter’s Deliverance:353 +Painted Bluffs:348 +Renewed Faith:337 +Hazoret’s Favor:305 +Violent Impact:284 +Haze of Pollen:277 +Scarab Feast:268 +Compelling Argument:265 +Embalmer’s Tools:260 +Luxa River Shrine:213 +By Force:201 +Ancient Crab:198 +Sunscorched Desert:186 +Dispossess:109 +Protection of the Hekma:108 +249 Gate to the Afterlife 95 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/dom.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/dom.csv new file mode 100644 index 0000000000..b14997dc93 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/dom.csv @@ -0,0 +1,249 @@ +Lyra Dawnbringer:2375 +Karn, Scion of Urza:2372 +Shalai, Voice of Plenty:2234 +Teferi, Hero of Dominaria:2215 +Verix Bladewing:2207 +Aryel, Knight of Windgrace:2166 +Multani, Yavimaya’s Avatar:2150 +History of Benalia:2123 +Siege-Gang Commander:2091 +In Bolas’s Clutches:2047 +Josu Vess, Lich Knight:2044 +Cast Down:2025 +Demonlord Belzenlok:2016 +Eviscerate:2010 +Serra Angel:2000 +Slimefoot, the Stowaway:1995 +Seal Away:1985 +Tatyova, Benthic Druid:1981 +Zahid, Djinn of the Lamp:1971 +Darigaaz Reincarnated:1959 +Weatherlight:1952 +Phyrexian Scriptures:1951 +Forebear’s Blade:1928 +Adeliz, the Cinder Wind:1919 +The Eldest Reborn:1919 +Teshar, Ancestor’s Apostle:1913 +Territorial Allosaurus:1896 +Danitha Capashen, Paragon:1895 +Muldrotha, the Gravetide:1881 +Fight with Fire:1879 +Shivan Fire:1879 +Helm of the Host:1876 +Knight of Grace:1863 +Vicious Offering:1859 +Pegasus Courser:1856 +Icy Manipulator:1849 +Benalish Marshal:1837 +Untamed Kavu:1836 +Goblin Chainwhirler:1834 +Raff Capashen, Ship’s Mage:1834 +Blessed Light:1833 +Rite of Belzenlok:1827 +Naru Meha, Master Wizard:1824 +Grand Warlord Radha:1817 +Two-Headed Giant:1817 +Llanowar Elves:1815 +Shanna, Sisay’s Legacy:1814 +Steel Leaf Champion:1811 +Song of Freyalise:1807 +Settle the Score:1804 +Time of Ice:1804 +Grunn, the Lonely King:1793 +Knight of Malice:1786 +Arvad the Cursed:1783 +Jhoira, Weatherlight Captain:1780 +Saproling Migration:1780 +Wizard’s Lightning:1779 +Tempest Djinn:1777 +Urgoros, the Empty One:1773 +Cloudreader Sphinx:1769 +Baloth Gorger:1768 +Skittering Surveyor:1765 +Baird, Steward of Argive:1762 +Blackblade Reforged:1760 +Hallar, the Firefletcher:1760 +On Serra’s Wings:1753 +Evra, Halcyon Witness:1748 +Traxos, Scourge of Kroog:1746 +Blink of an Eye:1742 +Triumph of Gerrard:1725 +Deep Freeze:1723 +Kazarov, Sengir Pureblood:1718 +Tiana, Ship’s Caretaker:1712 +Merfolk Trickster:1709 +Squee, the Immortal:1708 +Valduk, Keeper of the Flame:1708 +Kwende, Pride of Femeref:1707 +Whisper, Blood Liturgist:1707 +Academy Drake:1705 +Jaya Ballard:1704 +Gideon’s Reproach:1703 +Warcry Phoenix:1703 +Sporecrown Thallid:1698 +Yavimaya Sapherd:1692 +Rona, Disciple of Gix:1686 +Wizard’s Retort:1684 +Elfhame Druid:1683 +Fiery Intervention:1682 +Torgaar, Famine Incarnate:1682 +Yawgmoth’s Vile Offering:1677 +Deathbloom Thallid:1665 +Fungal Infection:1662 +Daring Archaeologist:1658 +Cold-Water Snapper:1656 +Thorn Elemental:1656 +Call the Cavalry:1649 +Sylvan Awakening:1648 +Jaya’s Immolating Inferno:1646 +Verdant Force:1642 +Fungal Plots:1636 +Spore Swarm:1635 +Divination:1629 +Syncopate:1626 +Marwyn, the Nurturer:1625 +Sergeant-at-Arms:1625 +Garna, the Bloodflame:1624 +Ghitu Chronicler:1622 +Tetsuko Umezawa, Fugitive:1612 +Dread Shade:1602 +Stronghold Confessor:1601 +Academy Journeymage:1599 +Chainer’s Torment:1593 +Thallid Omnivore:1592 +Thallid Soothsayer:1592 +Jousting Lance:1587 +Firefist Adept:1581 +Goblin Barrage:1580 +Naban, Dean of Iteration:1579 +Caligo Skin-Witch:1577 +Karn’s Temporal Sundering:1577 +Keldon Overseer:1574 +Dauntless Bodyguard:1572 +Opt:1572 +Ghitu Journeymage:1570 +The Mending of Dominaria:1568 +The Mirari Conjecture:1568 +Wild Onslaught:1567 +Haphazard Bombardment:1566 +Skizzik:1565 +Mammoth Spider:1558 +Serra Disciple:1558 +Clifftop Retreat:1557 +Aven Sentry:1556 +Mishra’s Self-Replicator:1552 +Ancient Animus:1550 +D’Avenant Trapper:1550 +Gilded Lotus:1549 +Jhoira’s Familiar:1548 +Champion of the Flame:1547 +Ghitu Lavarunner:1547 +Woodland Cemetery:1543 +Keldon Raider:1541 +Grow from the Ashes:1536 +Radiating Lightning:1536 +Sanctum Spirit:1533 +Windgrace Acolyte:1532 +Urza’s Ruinous Blast:1531 +Sulfur Falls:1527 +The Antiquities War:1522 +Adamant Will:1519 +Goblin Warchief:1518 +Adventurous Impulse:1516 +Mesa Unicorn:1512 +Bloodtallow Candle:1510 +Hinterland Harbor:1509 +Lingering Phantom:1506 +Short Sword:1499 +Llanowar Scout:1495 +Juggernaut:1493 +Frenzied Rage:1490 +Slinn Voda, the Rising Deep:1489 +Dub:1484 +Cabal Paladin:1482 +Gift of Growth:1482 +Dark Bargain:1481 +Benalish Honor Guard:1480 +Isolated Chapel:1473 +Kamahl’s Druidic Vow:1472 +Memorial to Glory:1469 +Sentinel of the Pearl Trident:1466 +Krosan Druid:1465 +Guardians of Koilos:1457 +Llanowar Envoy:1455 +Pardic Wanderer:1450 +Soul Salvage:1449 +The Flame of Keld:1448 +Arcane Flight:1445 +Divest:1444 +Feral Abomination:1441 +Artificer’s Assistant:1439 +Memorial to Unity:1439 +Yargle, Glutton of Urborg:1436 +Sparring Construct:1431 +Mox Amber:1429 +Weight of Memory:1426 +Precognition Field:1424 +The First Eruption:1420 +Invoke the Divine:1414 +Unwind:1413 +Primordial Wurm:1409 +Bloodstone Goblin:1408 +Vodalian Arcanist:1401 +Cabal Stronghold:1400 +Urza’s Tome:1393 +Lich’s Mastery:1390 +Primevals’ Glorious Rebirth:1390 +Run Amok:1390 +Gaea’s Protector:1382 +Pierce the Sky:1382 +Relic Runner:1381 +Jodah, Archmage Eternal:1378 +Excavation Elephant:1377 +Knight of New Benalia:1377 +Aesthir Glider:1376 +Befuddle:1375 +Homarid Explorer:1372 +Memorial to Folly:1371 +Howling Golem:1369 +Voltaic Servant:1369 +Nature’s Spiral:1368 +Sorcerer’s Wand:1366 +Corrosive Ooze:1360 +Broken Bond:1357 +Curator’s Ward:1355 +Tolarian Scholar:1354 +Memorial to Genius:1349 +Rampaging Cyclops:1347 +Warlord’s Fury:1328 +Fervent Strike:1321 +Demonic Vigor:1320 +Keldon Warcaller:1319 +Arbor Armament:1314 +Final Parting:1313 +Diligent Excavator:1312 +Navigator’s Compass:1308 +Charge:1307 +Amaranthine Wall:1305 +Cabal Evangel:1305 +Fire Elemental:1304 +Shield of the Realm:1304 +Oath of Teferi:1300 +Tragic Poet:1283 +Blessing of Belzenlok:1272 +Board the Weatherlight:1258 +Thran Temporal Gateway:1256 +Drudge Sentinel:1248 +Orcish Vandal:1247 +Skirk Prospector:1246 +Zhalfirin Void:1239 +Sage of Lat-Nam:1232 +Rescue:1225 +Gaea’s Blessing:1218 +Healing Grace:1200 +Rat Colony:1191 +Powerstone Shard:1162 +Seismic Shift:1152 +Damping Sphere:1133 +Fall of the Thran:1104 +Memorial to War:1089 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/grn.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/grn.csv new file mode 100644 index 0000000000..b8ec123486 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/grn.csv @@ -0,0 +1,259 @@ +Doom Whisperer:2332 +Aurelia, Exemplar of Justice:2258 +Vraska, Golgari Queen:2211 +Ral, Izzet Viceroy:2196 +Dream Eater:2180 +Thief of Sanity:2164 +Assassin's Trophy:2153 +Trostani Discordant:2141 +Beast Whisperer:2102 +Nullhide Ferox:2102 +Legion Warboss:2100 +March of the Multitudes:2094 +Conclave Tribunal:2092 +Niv-Mizzet, Parun:2088 +Light of the Legion:2073 +Price of Fame:2036 +Etrata, the Silencer:2019 +Venerated Loxodon:2017 +Justice Strike:2016 +Tajic, Legion's Edge:2005 +Underrealm Lich:1985 +Pelt Collector:1984 +Izoni, Thousand-Eyed:1977 +Find // Finality:1976 +Lazav, the Multifarious:1973 +Nightveil Sprite:1968 +Midnight Reaper:1964 +Lava Coil:1963 +Watcher in the Mist:1961 +Response // Resurgence:1958 +Knight of Autumn:1950 +Dimir Spybug:1948 +Integrity // Intervention:1945 +Nightveil Predator:1943 +Emmara, Soul of the Accord:1942 +Luminous Bonds:1932 +Artful Takedown:1923 +Ritual of Soot:1914 +Blood Operative:1903 +Conclave Cavalier:1902 +Truefire Captain:1902 +Runaway Steam-Kin:1901 +Murmuring Mystic:1899 +Arclight Phoenix:1894 +Risk Factor:1893 +Boros Challenger:1887 +Dead Weight:1887 +Bounty of Might:1886 +Connive // Concoct:1886 +Status // Statue:1885 +Deadly Visit:1878 +Deafening Clarion:1878 +Roc Charger:1864 +Kraul Harpooner:1839 +Citywatch Sphinx:1837 +Assure // Assemble:1836 +Expansion // Explosion:1836 +Capture Sphere:1834 +Thoughtbound Phantasm:1832 +Crackling Drake:1830 +Dawn of Hope:1827 +Disinformation Campaign:1826 +House Guildmage:1824 +Quasiduplicate:1816 +Sunhome Stalwart:1815 +Skyknight Legionnaire:1805 +Darkblade Agent:1788 +Plaguecrafter:1786 +Goblin Cratermaker:1773 +Affectionate Indrik:1772 +Whisper Agent:1771 +Notion Rain:1761 +Ledev Champion:1757 +Charnel Troll:1751 +Thought Erasure:1750 +Golgari Findbroker:1749 +Chemister's Insight:1743 +Goblin Banneret:1737 +Swiftblade Vindicator:1736 +Command the Storm:1728 +Camaraderie:1726 +Wee Dragonauts:1723 +District Guide:1722 +Hypothesizzle:1715 +League Guildmage:1712 +Direct Current:1711 +Experimental Frenzy:1711 +Discovery // Dispersal:1708 +Rampaging Monument:1705 +Rosemane Centaur:1698 +Inescapable Blaze:1693 +Watery Grave:1687 +Legion Guildmage:1680 +Chamber Sentry:1674 +Inspiring Unicorn:1671 +Ionize:1669 +Flower // Flourish:1663 +Divine Visitation:1656 +Dimir Informant:1653 +Healer's Hawk:1651 +Conclave Guildmage:1648 +Sinister Sabotage:1647 +Parhelion Patrol:1640 +Ochran Assassin:1639 +Goblin Electromancer:1634 +Glowspore Shaman:1631 +Siege Wurm:1629 +Wojek Bodyguard:1629 +Hellkite Whelp:1626 +Hired Poisoner:1625 +Unexplained Disappearance:1625 +Overgrown Tomb:1624 +Prey Upon:1624 +Pitiless Gorgon:1622 +Flight of Equenauts:1621 +Hatchery Spider:1621 +Temple Garden:1621 +Beacon Bolt:1620 +Citywide Bust:1615 +Bounty Agent:1613 +Piston-Fist Cyclops:1605 +Steam Vents:1600 +Erratic Cyclops:1582 +Swarm Guildmage:1582 +Sacred Foundry:1581 +Mission Briefing:1580 +Muse Drake:1574 +Arboretum Elemental:1572 +Worldsoul Colossus:1572 +Skyline Scout:1569 +Smelt-Ward Minotaur:1568 +Burglar Rat:1561 +Whispering Snitch:1560 +Fresh-Faced Recruit:1555 +Necrotic Wound:1554 +Electrostatic Field:1541 +Disdainful Stroke:1534 +Gruesome Menagerie:1534 +Sprouting Renewal:1534 +Sonic Assault:1533 +Sure Strike:1527 +Severed Strands:1522 +Beamsplitter Mage:1521 +Chromatic Lantern:1516 +Ledev Guardian:1510 +Radical Idea:1502 +Pilfering Imp:1500 +Vernadi Shieldmate:1497 +Ornery Goblin:1495 +Gatekeeper Gargoyle:1489 +Barging Sergeant:1484 +Blade Instructor:1483 +Rhizome Lurcher:1481 +Invert // Invent:1477 +Ironshell Beetle:1477 +Generous Stray:1474 +Demotion:1469 +Might of the Masses:1468 +Molderhulk:1467 +Selective Snare:1466 +Hammer Dropper:1463 +Swathcutter Giant:1462 +Firemind's Research:1460 +Devkarin Dissident:1459 +Mnemonic Betrayal:1459 +Vigorspore Wurm:1459 +Haazda Marshal:1457 +Lotleth Giant:1455 +Righteous Blow:1451 +Fire Urchin:1446 +Gird for Battle:1441 +Kraul Swarm:1437 +Veiled Shade:1437 +Centaur Peacemaker:1434 +Golgari Raiders:1434 +Passwall Adept:1434 +Sworn Companions:1434 +Erstwhile Trooper:1432 +Hunted Witness:1431 +Kraul Foragers:1431 +Collar the Culprit:1427 +Mausoleum Secrets:1424 +Take Heart:1424 +Dazzling Lights:1419 +Rubblebelt Boar:1418 +Sumala Woodshaper:1418 +Intrusive Packbeast:1416 +Loxodon Restorer:1415 +Omnispell Adept:1415 +Spinal Centipede:1415 +Glaive of the Guildpact:1414 +Vivid Revival:1410 +Douser of Lights:1409 +Devious Cover-Up:1404 +Chance for Glory:1402 +Child of Night:1402 +Enhanced Surveillance:1399 +Hitchclaw Recluse:1398 +Mephitic Vapors:1395 +Circuitous Route:1389 +Cosmotronic Wave:1389 +Leapfrog:1379 +Goblin Locksmith:1377 +Guildmages' Forum:1370 +Guild Summit:1368 +Bartizan Bats:1367 +Undercity Uprising:1363 +Thousand-Year Storm:1355 +Drowned Secrets:1349 +Boros Guildgate :1345 +Grappling Sundew:1344 +Boros Guildgate :1343 +Tenth District Guard:1342 +Izzet Guildgate :1338 +Crushing Canopy:1335 +Portcullis Vine:1333 +Undercity Necrolisk:1332 +Dimir Guildgate :1331 +Barrier of Bones:1327 +Wild Ceratok:1327 +Izzet Guildgate :1326 +Gravitic Punch:1320 +Silent Dart:1310 +Wary Okapi:1309 +Pack's Favor:1307 +Garrison Sergeant:1303 +Vedalken Mesmerist:1303 +Golgari Guildgate :1295 +Golgari Guildgate :1286 +Dimir Guildgate :1280 +Maniacal Rage:1280 +Selesnya Guildgate :1280 +Urban Utopia:1278 +Wall of Mist:1273 +Maximize Altitude:1268 +Join Shields:1267 +Selesnya Guildgate :1266 +Book Devourer:1263 +Wishcoin Crab:1262 +Narcomoeba:1257 +Crush Contraband:1248 +Gateway Plaza:1248 +Fearless Halberdier:1246 +Torch Courier:1242 +Candlelight Vigil:1241 +Moodmark Painter:1230 +Creeping Chill:1218 +Izzet Locket:1217 +Dimir Locket:1202 +Maximize Velocity:1200 +Unmoored Ego:1184 +Never Happened:1175 +Golgari Locket:1173 +Selesnya Locket:1154 +Boros Locket:1128 +Street Riot:1110 +Vicious Rumors:1101 +Pause for Reflection:1089 +Wand of Vertebrae:1073 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/hou.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/hou.csv new file mode 100644 index 0000000000..5687f1f849 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/hou.csv @@ -0,0 +1,184 @@ +The Scarab God:2272 +Angel of Condemnation:2079 +The Locust God:2077 +The Scorpion God:2048 +Pride Sovereign:2046 +Crested Sunmare:1996 +Nicol Bolas, God-Pharaoh:1965 +Majestic Myriarch:1915 +Neheb, the Eternal:1906 +Hour of Devastation:1901 +Adorned Pouncer:1889 +Ammit Eternal:1881 +Samut, the Tested:1874 +Razaketh, the Foulblooded:1856 +Grind // Dust:1855 +Resilient Khenra:1832 +Sand Strangler:1822 +Ramunap Hydra:1818 +Abrade:1816 +Desert’s Hold:1813 +Champion of Wits:1810 +Bontu’s Last Reckoning:1807 +Nimble Obstructionist:1796 +Chaos Maw:1788 +Sifter Wurm:1783 +Unesh, Criosphinx Sovereign:1776 +Hour of Glory:1771 +River Hoopoe:1769 +Ominous Sphinx:1754 +Torment of Hailfire:1754 +Open Fire:1751 +Torment of Venom:1743 +Dreamstealer:1740 +Struggle // Survive:1737 +Burning-Fist Minotaur:1734 +Ambuscade:1732 +God-Pharaoh’s Gift:1731 +Accursed Horde:1729 +Doomfall:1727 +Earthshaker Khenra:1716 +Aerial Guide:1711 +Khenra Scrapper:1709 +Oketra’s Avenger:1691 +Bloodwater Entity:1689 +Rhonas’s Last Stand:1686 +Angel of the God-Pharaoh:1685 +Tenacious Hunter:1685 +Hour of Promise:1684 +Eternal of Harsh Truths:1680 +Fervent Paincaster:1677 +Lethal Sting:1673 +Vizier of the Anointed:1673 +Wildfire Eternal:1671 +Puncturing Blow:1668 +Sandblast:1668 +Sunscourge Champion:1661 +Spellweaver Eternal:1656 +Vizier of the True:1656 +Banewhip Punisher:1652 +Kefnet’s Last Word:1652 +Merciless Eternal:1648 +Vile Manifestation:1647 +Bitterbow Sharpshooters:1646 +Driven // Despair:1643 +Supreme Will:1638 +Hour of Revelation:1637 +Torment of Scarabs:1637 +Oasis Ritualist:1636 +Farm // Market:1628 +Unraveling Mummy:1628 +Obelisk Spider:1617 +Mirage Mirror:1615 +Manticore Eternal:1613 +Resolute Survivors:1610 +Ruin Rat:1610 +Overwhelming Splendor:1608 +Unconventional Tactics:1608 +Hour of Eternity:1606 +Devotee of Strength:1605 +Sinuous Striker:1604 +Sunset Pyramid:1602 +Riddleform:1600 +Solitary Camel:1600 +Harrier Naga:1598 +Steward of Solidarity:1597 +Sidewinder Naga:1595 +Dauntless Aven:1591 +Feral Prowler:1591 +Thorned Moloch:1586 +Striped Riverwinder:1584 +Frontline Devastator:1580 +Appeal // Authority:1578 +Aven of Enduring Hope:1577 +Mummy Paramount:1571 +Uncage the Menagerie:1570 +Consign // Oblivion:1564 +Hollow One:1561 +Aven Reedstalker:1560 +Rhonas’s Stalwart:1559 +Unsummon:1557 +Desert of the Glorified:1556 +Manalith:1555 +Hope Tender:1551 +Granitic Titan:1550 +Ifnir Deadlands:1550 +Blur of Blades:1547 +Marauding Boneslasher:1547 +Shefet Dunes:1547 +Claim // Fame:1545 +Magmaroth:1545 +Beneath the Sands:1543 +Ramunap Excavator:1542 +Desert of the Mindful:1541 +Khenra Eternal:1541 +Reason // Believe:1541 +Rampaging Hippo:1540 +Unquenchable Thirst:1539 +Razaketh’s Rite:1537 +Saving Grace:1532 +Steadfast Sentinel:1531 +Wall of Forgotten Pharaohs:1531 +Imminent Doom:1530 +Defiant Khenra:1526 +Cunning Survivor:1525 +Ramunap Ruins:1525 +Hashep Oasis:1524 +Overcome:1523 +Abandoned Sarcophagus:1514 +Carrion Screecher:1514 +Firebrand Archer:1510 +Frilled Sandwalla:1507 +Hazoret’s Undying Fury:1505 +Inferno Jet:1499 +Crypt of the Eternals:1496 +Gift of Strength:1495 +Kindled Fury:1493 +Ipnu Rivulet:1492 +Act of Heroism:1491 +Without Weakness:1489 +Desert of the Indomitable:1487 +Fraying Sanity:1485 +Hostile Desert:1484 +Traveler’s Amulet:1482 +God-Pharaoh’s Faithful:1477 +Desert of the Fervent:1476 +Apocalypse Demon:1474 +Wretched Camel:1472 +Dagger of the Worthy:1468 +Refuse // Cooperate:1468 +Quarry Beetle:1464 +Countervailing Winds:1460 +Gilded Cerodon:1455 +Djeru, With Eyes Open:1450 +Strategic Planning:1450 +Tragic Lesson:1449 +Scrounger of Souls:1447 +Dune Diviner:1438 +Desert of the True:1436 +Chandra’s Defeat:1433 +Proven Combatant:1430 +Survivors’ Encampment:1427 +Djeru’s Renunciation:1425 +Disposal Mummy:1422 +Imaginary Threats:1418 +Moaning Wall:1416 +Dutiful Servants:1403 +Oketra’s Last Mercy:1403 +Crash Through:1400 +Lurching Rotbeast:1397 +Swarm Intelligence:1397 +Life Goes On:1395 +Grisly Survivor:1388 +Dunes of the Dead:1381 +Jace’s Defeat:1369 +Endless Sands:1367 +Seer of the Last Tomorrow:1360 +Graven Abomination:1352 +Gideon’s Defeat:1346 +Liliana’s Defeat:1345 +Leave // Chance:1324 +Solemnity:1265 +Scavenger Grounds:1256 +Crook of Condemnation:1228 +Nissa’s Defeat:1185 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ima.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ima.csv new file mode 100644 index 0000000000..d9afedab23 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ima.csv @@ -0,0 +1,249 @@ +Consecrated Sphinx:2182 +Ancestral Vision:2144 +Archangel of Thune:2141 +Elesh Norn, Grand Cenobite:2135 +Mana Drain:2124 +Urabrask the Hidden:2107 +Sheoldred, Whispering One:2106 +Swords to Plowshares:2106 +Primeval Titan:2103 +Ob Nixilis, the Fallen:2081 +Doom Blade:2064 +Rampaging Baloths:2056 +Thundermaw Hellkite:2053 +Restoration Angel:2044 +Keiga, the Tide Star:2042 +Avacyn, Angel of Hope:2029 +Kiki-Jiki, Mirror Breaker:2024 +Kokusho, the Evening Star:2020 +Cryptic Command:2012 +Supreme Verdict:2002 +Genesis Hydra:2001 +Fireball:2000 +Emeria Angel:1992 +Austere Command:1969 +Blood Baron of Vizkopa:1968 +Lotus Cobra:1955 +Sphinx of Uthuun:1927 +Yosei, the Morning Star:1924 +Rift Bolt:1912 +Scourge of Valkas:1909 +Bogardan Hellkite:1907 +Ryusei, the Falling Star:1907 +Spiritmonger:1900 +Vorinclex, Voice of Hunger:1897 +Indulgent Tormentor:1888 +Heroes’ Bane:1885 +Jugan, the Rising Star:1877 +Simic Sky Swallower:1874 +Serra Angel:1873 +Grisly Spectacle:1865 +Rune-Scarred Demon:1864 +Channel:1861 +Hypersonic Dragon:1856 +Lightning Helix:1856 +Teferi, Mage of Zhalfir:1854 +Knight of the Reliquary:1848 +Thran Dynamo:1848 +Thoughtseize:1839 +Anger of the Gods:1836 +Savageborn Hydra:1829 +Charmbreaker Devils:1828 +Staggershock:1824 +Malfegor:1812 +Palladium Myr:1808 +Draconic Roar:1796 +Ulcerate:1795 +Heat Ray:1794 +Mahamoti Djinn:1793 +Hoarding Dragon:1786 +Corpsejack Menace:1783 +Abyssal Persecutor:1774 +Firemane Angel:1771 +Curse of Predation:1766 +Electrolyze:1754 +Reave Soul:1754 +Oblivion Stone:1744 +Overgrown Battlement:1738 +Claustrophobia:1736 +Obstinate Baloth:1732 +Blizzard Specter:1724 +Pillar of Flame:1724 +Wall of Roots:1723 +Undercity Troll:1721 +Cephalid Broker:1717 +Abzan Battle Priest:1716 +Abzan Falconer:1698 +Mind Stone:1697 +Illusory Ambusher:1691 +Fog Bank:1690 +Mana Leak:1689 +Genesis Wave:1686 +Condescend:1685 +Rosheen Meanderer:1682 +Aether Vial:1681 +Wing Shards:1680 +Bladewing the Risen:1677 +Vizkopa Guildmage:1671 +Aetherize:1669 +Bloodghast:1667 +Horizon Canopy:1662 +Noxious Dragon:1661 +Seeker of the Way:1657 +Azorius Charm:1650 +Topan Freeblade:1650 +Ajani’s Pridemate:1649 +Guttersnipe:1648 +Orzhov Basilica:1648 +Necropotence:1645 +Prodigal Pyromancer:1641 +Monastery Swiftspear:1639 +Phantom Monster:1637 +Search for Tomorrow:1637 +Phyrexian Rager:1630 +Frost Lynx:1624 +Carven Caryatid:1621 +Hunt the Weak:1621 +Izzet Boilerworks:1620 +Blinding Mage:1616 +Amass the Components:1610 +Iona’s Judgment:1605 +Repeal:1602 +Serra Ascendant:1601 +Star Compass:1600 +Kiln Fiend:1597 +Simic Growth Chamber:1596 +Auriok Champion:1592 +Illusory Angel:1588 +Day of the Dragons:1587 +Jungle Barrier:1586 +Rakdos Carnarium:1586 +Dimir Aqueduct:1575 +Golgari Rot Farm:1572 +Jin-Gitaxias, Core Augur:1570 +Bladewing’s Thrall:1562 +Mnemonic Wall:1562 +Ainok Bond-Kin:1561 +Crowned Ceratok:1556 +Jhessian Thief:1555 +Boros Garrison:1551 +Selesnya Sanctuary:1551 +Grove of the Burnwillows:1547 +Chronicler of Heroes:1546 +Glimpse the Unthinkable:1543 +Manakin:1537 +Riverwheel Aerialists:1531 +Guardian Idol:1525 +Assault Formation:1520 +Graven Cairns:1520 +Mer-Ek Nightblade:1519 +Stalwart Aven:1518 +Netcaster Spider:1516 +Angelic Accord:1514 +Doomed Traveler:1514 +Thrill-Kill Assassin:1514 +Distortion Strike:1511 +Azorius Chancery:1509 +Skywise Teachings:1503 +Borderland Marauder:1497 +Sustainer of the Realm:1495 +Furnace Whelp:1494 +Sultai Flayer:1493 +Ivy Elemental:1490 +Darksteel Axe:1487 +Gruul Turf:1486 +Path of Bravery:1485 +Wight of Precinct Six:1480 +Dissolve:1477 +Doorkeeper:1476 +Evolving Wilds:1472 +Keldon Halberdier:1468 +Foul-Tongue Invocation:1465 +Durkwood Baloth:1462 +Nantuko Shaman:1462 +Vent Sentinel:1461 +Scion of Ugin:1460 +Splatter Thug:1459 +Mishra’s Bauble:1458 +Child of Night:1454 +Ojutai’s Breath:1454 +Night of Souls’ Betrayal:1449 +Greater Basilisk:1448 +Butcher’s Glee:1446 +Surreal Memoir:1443 +Magus of the Moon:1438 +Battle-Rattle Shaman:1435 +Guard Duty:1429 +Sandstone Oracle:1426 +Enlarge:1425 +Jace’s Phantasm:1425 +Pristine Talisman:1424 +Duskdale Wurm:1423 +Elusive Spellfist:1423 +Dragon Egg:1421 +Flusterstorm:1421 +Kolaghan Monument:1415 +Balustrade Spy:1410 +Dragon Bell Monk:1407 +Student of Ojutai:1407 +Dragon Tempest:1406 +Angel of Mercy:1405 +Dragonloft Idol:1395 +Sanguine Bond:1394 +Dead Reveler:1393 +Wrench Mind:1393 +Diminish:1392 +Wildsize:1392 +Windfall:1392 +Guided Strike:1391 +Survival Cache:1391 +Lord of the Pit:1390 +Nimbus Maze:1390 +Rakdos Drake:1384 +Phantom Tiger:1381 +River of Tears:1381 +Moonglove Extract:1380 +Timberland Guide:1378 +Trepanation Blade:1378 +Burrenton Forge-Tender:1376 +Virulent Swipe:1376 +Hunting Pack:1367 +Fury Charm:1364 +Infantry Veteran:1360 +Coordinated Assault:1356 +Jaddi Offshoot:1353 +Inspiring Call:1350 +Shriekgeist:1349 +Thought Scour:1345 +Pentarch Ward:1344 +Bogbrew Witch:1343 +Tavern Swindler:1342 +Prey’s Vengeance:1341 +Serum Powder:1340 +Rotfeaster Maggot:1338 +Emerge Unscathed:1322 +Lead the Stampede:1322 +Bala Ged Scorpion:1321 +Dragonlord’s Servant:1321 +Great Teacher’s Decree:1313 +Eternal Thirst:1312 +Hammerhand:1302 +Haunting Hymn:1301 +Festering Newt:1287 +Tormenting Voice:1286 +Earth Elemental:1278 +Benevolent Ancestor:1264 +Trumpet Blast:1253 +Bewilder:1252 +Mark of Mutiny:1245 +Crucible of Fire:1242 +Bubbling Cauldron:1241 +Duress:1236 +Lure:1228 +Mindcrank:1225 +Radiant Fountain:1224 +Disenchant:1215 +Runed Servitor:1213 +Aerial Predation:1196 +Shimmering Grotto:1163 +Nature’s Claim:1137 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/kld.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/kld.csv new file mode 100644 index 0000000000..d586ce8d8c --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/kld.csv @@ -0,0 +1,184 @@ +Ajani Unyielding:40114 +Herald of Anguish:39905 +Rishkar, Peema Renegade:39137 +Aethersphere Harvester:38827 +Heart of Kiran:37403 +Yahenni’s Expertise:37199 +Tezzeret the Schemer:34694 +Solemn Recruit:34338 +Untethered Express:33419 +Battle at the Bridge:33072 +Yahenni, Undying Partisan:32377 +Fatal Push:32126 +Sram’s Expertise:32076 +Walking Ballista:31052 +Baral’s Expertise:30879 +Freejam Regent:30870 +Glint-Sleeve Siphoner:30022 +Ridgescale Tusker:30018 +Quicksmith Spy:29214 +Scrapper Champion:29176 +Aethertide Whale:28976 +Daring Demolition:28538 +Gifted Aetherborn:28163 +Quicksmith Rebel:27792 +Hungry Flames:27737 +Thopter Arrest:27574 +Exquisite Archangel:27415 +Kari Zev, Skyship Raider:27188 +Aetherwind Basker:26371 +Treasure Keeper:26283 +Greenbelt Rampager:26185 +Vengeful Rebel:25902 +Aethergeode Miner:25711 +Rishkar’s Expertise:25327 +Lightning Runner:25297 +Shock:25129 +Caught in the Brights:24815 +Lifecrafter’s Bestiary:24466 +Midnight Entourage:23732 +Sram, Senior Edificer:23386 +Metallic Mimic:23383 +Maulfist Revolutionary:23093 +Greenwheel Liberator:21817 +Chandra’s Revolution:21713 +Maverick Thopterist:21685 +Airdrop Aeronauts:21061 +Narnam Renegade:20406 +Winding Constrictor:20174 +Scrap Trawler:20001 +Monstrous Onslaught:19528 +Wind-Kin Raiders:19507 +Deadeye Harpooner:19305 +Skyship Plunderer:18967 +Aether Poisoner:18617 +Cruel Finality:18352 +Release the Gremlins:18286 +Aether Chaser:17813 +Rogue Refiner:17646 +Reckless Racer:17299 +Dawnfeather Eagle:17238 +Felidar Guardian:17122 +Prey Upon:16986 +Spire Patrol:16942 +Druid of the Cowl:16941 +Aetherstream Leopard:16826 +Reverse Engineer:15858 +Daredevil Dragster:15795 +Shielded Aether Thief:15596 +Scrounging Bandar:14827 +Lifecraft Cavalry:14821 +Pacification Array:14672 +Renegade Rallier:14442 +Trophy Mage:14084 +Enraged Giant:13989 +Foundry Hornet:13907 +Call for Unity:13832 +Renegade Wheelsmith:13717 +Peacewalker Colossus:13604 +Sweatworks Brawler:13229 +Aether Swooper:13171 +Outland Boar:13074 +Restoration Specialist:12713 +Perilous Predicament:12702 +Aeronaut Admiral:12409 +Tezzeret’s Touch:12281 +Oath of Ajani:11663 +Bastion Inventor:11485 +Weldfast Engineer:11309 +Countless Gears Renegade:11144 +Mechanized Production:10887 +Hinterland Drake:10667 +Consulate Crackdown:10549 +Renegade Map:10115 +Peema Aether-Seer:9906 +Unbridled Growth:9661 +Lifecraft Awakening:9620 +Baral, Chief of Compliance:9382 +Merchant’s Dockhand:9033 +Barricade Breaker:8635 +Lifecrafter’s Gift:8248 +Hidden Herbalists:8012 +Mobile Garrison:7976 +Aether Herder:7964 +Disallow:7550 +Kari Zev’s Expertise:7472 +Cogwork Assembler:7463 +Heroic Intervention:6922 +Hidden Stockpile:6732 +Illusionist’s Stratagem:6678 +Leave in the Dust:6675 +Ghirapur Osprey:6597 +Decommission:6354 +Ice Over:6297 +Night Market Aeronaut:6198 +Gremlin Infestation:6195 +Spire of Industry:6181 +Audacious Infiltrator:6084 +Sly Requisitioner:5718 +Alley Strangler:5595 +Silkweaver Elite:5574 +Aid from the Cowl:5463 +Highspire Infusion:5402 +Frontline Rebel:5350 +Invigorated Rampage:5268 +Defiant Salvager:5211 +Watchful Automaton:5147 +Siege Modification:5142 +Inspiring Statuary:4932 +Embraal Gear-Smasher:4847 +Deft Dismissal:4727 +Shipwreck Moray:4645 +Metallic Rebuke:4618 +Dispersal Technician:4389 +Resourceful Return:4325 +Efficient Construction:4108 +Welder Automaton:4076 +Aether Inspector:3989 +Ravenous Intruder:3963 +Ironclad Revolutionary:3930 +Implement of Ferocity:3720 +Alley Evasion:3712 +Hope of Ghirapur:3699 +Aerial Modification:3671 +Gonti’s Aether Heart:3295 +Foundry Assembler:3292 +Fen Hauler:3265 +Natural Obsolescence:3262 +Destructive Tampering:3239 +Implement of Examination:3217 +Irontread Crusher:3097 +Filigree Crawler:3020 +Servo Schematic:3006 +Verdant Automaton:2979 +Reservoir Walker:2918 +Whir of Invention:2916 +Paradox Engine:2714 +Salvage Scuttler:2677 +Augmenting Automaton:2636 +Fourth Bridge Prowler:2448 +Conviction:2411 +Lathnu Sailback:2352 +Planar Bridge:2348 +Night Market Guard:2244 +Bastion Enforcer:2236 +Precise Strike:2179 +Universal Solvent:2128 +Implement of Malice:2089 +Crackdown Construct:1926 +Dark Intimations:1876 +Pia’s Revolution:1850 +Renegade’s Getaway:1472 +Aegis Automaton:1355 +Consulate Dreadnought:1255 +Indomitable Creativity:1206 +Negate:1016 +Consulate Turret:1014 +Implement of Combustion:806 +Take into Custody:678 +Implement of Improvement:624 +Wrangle:543 +Ornithopter:177 +Gonti’s Machinations:167 +Prizefighter Construct:123 +184 Secret Salvage 77 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/m19.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/m19.csv new file mode 100644 index 0000000000..82164b0866 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/m19.csv @@ -0,0 +1,260 @@ +Resplendent Angel:2323 +Tezzeret, Artifice Master:2297 +Ajani, Adversary of Tyrants:2268 +Vivien Reid:2257 +Nicol Bolas, the Ravager:2210 +Bone Dragon:2163 +Demanding Dragon:2122 +Murder:2118 +Banefire:2116 +Lathliss, Dragon Queen:2111 +Djinn of Wishes:2092 +Isareth the Awakener:2083 +Demon of Catastrophes:2078 +Leonin Warleader:2036 +Hieromancer's Cage:2031 +Lightning Strike:2030 +Goreclaw, Terror of Qal Sisma:1990 +Angel of the Dawn:1965 +Vine Mare:1962 +Cleansing Nova:1957 +Luminous Bonds:1957 +Hungering Hydra:1956 +Pelakka Wurm:1948 +Palladia-Mors, the Ruiner:1940 +Thorn Lieutenant:1931 +Rabid Bite:1929 +Dismissive Pyromancer:1919 +Lena, Selfless Champion:1914 +Herald of Faith:1911 +Sigiled Sword of Valeron:1906 +Vaevictis Asmadi, the Dire:1898 +Lich's Caress:1895 +Graveyard Marshal:1885 +Pegasus Courser:1878 +Chromium, the Mutable:1875 +Volcanic Dragon:1869 +Mentor of the Meek:1866 +Vampire Sovereign:1860 +Valiant Knight:1855 +Poison-Tip Archer:1851 +Spit Flame:1851 +Windreader Sphinx:1846 +Death Baron:1844 +Skyrider Patrol:1844 +Shock:1841 +Regal Bloodlord:1840 +Ajani's Pridemate:1836 +Psychic Symbiont:1833 +Liliana, Untouched by Death:1825 +Exclusion Mage:1824 +Star-Crowned Stag:1823 +Sleep:1817 +Heroic Reinforcements:1805 +Patient Rebuilding:1804 +Druid of the Cowl:1790 +Horizon Scholar:1784 +Skymarch Bloodletter:1777 +Sarkhan, Fireblood:1776 +Runic Armasaur:1774 +Prodigious Growth:1773 +Take Vengeance:1772 +Aven Wind Mage:1770 +Dryad Greenseeker:1761 +Electrify:1751 +Sarkhan's Unsealing:1743 +Plague Mare:1739 +Gallant Cavalry:1736 +Mystic Archaeologist:1724 +Draconic Disciple:1723 +Essence Scatter:1723 +Vigilant Baloth:1719 +Skeleton Archer:1717 +Arcades, the Strategist:1715 +Militia Bugler:1715 +Departed Deckhand:1713 +Fell Specter:1708 +Strangling Spores:1703 +Bristling Boar:1699 +Snapping Drake:1693 +Enigma Drake:1692 +Knightly Valor:1692 +Gravedigger:1690 +Sai, Master Thopterist:1688 +Aviation Pioneer:1685 +Skyscanner:1683 +Shield Mare:1680 +Meteor Golem:1674 +Sparktongue Dragon:1673 +Brawl-Bash Ogre:1667 +Remorseful Cleric:1666 +Sift:1663 +Fiery Finish:1654 +Transmogrifying Wand:1653 +Aerial Engineer:1649 +Cavalry Drillmaster:1648 +Ghastbark Twins:1645 +Reclamation Sage:1640 +Ajani's Last Stand:1637 +Metamorphic Alteration:1634 +Mirror Image:1633 +Omenspeaker:1633 +Vivien's Invocation:1633 +Dark-Dweller Oracle:1630 +Boggart Brute:1628 +Dwindle:1625 +Goblin Trashmaster:1625 +Make a Stand:1624 +Liliana's Contract:1623 +Giant Spider:1622 +Open the Graves:1621 +Colossal Dreadmaw:1616 +Divination:1615 +Goblin Instigator:1614 +Supreme Phantom:1613 +Chaos Wand:1605 +Rhox Oracle:1603 +Elvish Rejuvenator:1602 +Skilled Animator:1600 +Leonin Vanguard:1597 +Declare Dominance:1596 +Reassembling Skeleton:1595 +Daggerback Basilisk:1591 +Bone to Ash:1585 +Rise from the Grave:1585 +Gift of Paradise:1582 +Titanic Growth:1582 +Arcane Encyclopedia:1581 +Switcheroo:1581 +Doomed Dissenter:1579 +Gigantosaurus:1579 +Siegebreaker Giant:1577 +Child of Night:1575 +Surge Mare:1575 +Cancel:1561 +Volley Veteran:1560 +Epicure of Blood:1559 +Vampire Neonate:1555 +Guttersnipe:1554 +Aethershield Artificer:1553 +Rogue's Gloves:1553 +Macabre Waltz:1550 +Hired Blade:1548 +Salvager of Secrets:1545 +Diamond Mare:1543 +Blood Divination:1542 +Nightmare's Thirst:1542 +Gargoyle Sentinel:1539 +Act of Treason:1538 +Lightning Mare:1534 +Abnormal Endurance:1531 +Inspired Charge:1531 +Gearsmith Guardian:1527 +Dragon Egg:1521 +Anticipate:1519 +Viashino Pyromancer:1519 +Rustwing Falcon:1514 +Two-Headed Zombie:1513 +Blanchwood Armor:1511 +Hostile Minotaur:1510 +Druid of Horns:1508 +Marauder's Axe:1508 +Diregraf Ghoul:1507 +Havoc Devils:1506 +Satyr Enchanter:1505 +Centaur Courser:1502 +Plummet:1497 +Disperse:1494 +Sure Strike:1494 +Inferno Hellion:1491 +Novice Knight:1491 +Oakenform:1483 +Knight of the Tusk:1482 +Fountain of Renewal:1477 +Ravenous Harpy:1474 +Knight's Pledge:1469 +Thornhide Wolves:1463 +Dragon's Hoard:1461 +Daybreak Chaplain:1459 +Ghirapur Guide:1457 +Greenwood Sentinel:1456 +Recollect:1455 +Goblin Motivator:1452 +Talons of Wildwood:1449 +Colossal Majesty:1447 +Gearsmith Prodigy:1441 +Scholar of Stars:1439 +Ajani's Welcome:1433 +Mighty Leap:1432 +Naturalize:1431 +Trusty Packbeast:1431 +Dwarven Priest:1426 +Uncomfortable Chill:1423 +Oreskos Swiftclaw:1422 +Psychic Corrosion:1421 +Loxodon Line Breaker:1419 +Aether Tunnel:1404 +Frilled Sea Serpent:1403 +Infernal Scarring:1403 +Phylactery Lich:1398 +Mind Rot:1396 +Explosive Apparatus:1395 +Amulet of Safekeeping:1390 +Duress:1390 +Magistrate's Scepter:1388 +Suspicious Bookcase:1388 +Invoke the Divine:1385 +Manalith:1384 +Onakke Ogre:1384 +Tormenting Voice:1384 +One with the Machine:1378 +Meandering River:1374 +Lava Axe:1369 +Stone Quarry:1369 +Thud:1368 +Field Creeper:1367 +Rupture Spire:1366 +Elvish Clancaller:1365 +Wall of Mist:1363 +Suncleanser:1357 +Highland Game:1352 +Walking Corpse:1352 +Fire Elemental:1351 +Tectonic Rift:1348 +Totally Lost:1348 +Woodland Stream:1346 +Trumpet Blast:1339 +Millstone:1329 +Crash Through:1327 +Bogstomper:1326 +Aegis of the Heavens:1323 +Forsaken Sanctuary:1323 +Apex of Power:1307 +Tranquil Expanse:1304 +Cinder Barrens:1296 +Infernal Reckoning:1294 +Revitalize:1293 +Wall of Vines:1292 +Detection Tower:1283 +Timber Gorge:1282 +Submerged Boneyard:1277 +Mistcaller:1273 +Ghostform:1272 +Catalyst Elemental:1268 +Omniscience:1267 +Tolarian Scholar:1267 +Stitcher's Supplier:1263 +Desecrated Tomb:1258 +Scapeshift:1251 +Sovereign's Bite:1250 +Highland Lake:1245 +Infectious Horror:1241 +Doublecast:1240 +Fraying Omnipotence:1220 +Crucible of Worlds:1209 +Root Snare:1201 +Smelt:1199 +Reliquary Tower:1197 +Foul Orchard:1190 +Isolate:1139 +Alpine Moon:1068 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/mm3.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/mm3.csv new file mode 100644 index 0000000000..d088c3d513 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/mm3.csv @@ -0,0 +1,249 @@ +Jace, the Mind Sculptor:2196 +Master of the Wild Hunt:2148 +Lightning Bolt:2107 +Swords to Plowshares:2060 +Vendilion Clique:2058 +Ravenous Chupacabra:2057 +Courser of Kruphix:1981 +Reef Worm:1962 +Vindicate:1961 +Pillory of the Sleepless:1926 +Akroma, Angel of Fury:1923 +Gisela, Blade of Goldnight:1918 +Akroma, Angel of Wrath:1913 +Animar, Soul of Elements:1902 +Murder:1900 +Ruric Thar, the Unbowed:1896 +Protean Hulk:1894 +Pacifism:1888 +Akroma’s Vengeance:1885 +Murder of Crows:1885 +Phyrexian Obliterator:1882 +Rancor:1864 +Vesuvan Shapeshifter:1858 +Niv-Mizzet, the Firemind:1854 +Shadowmage Infiltrator:1854 +Fiend Hunter:1844 +Pernicious Deed:1841 +Thalia, Guardian of Thraben:1829 +Living Death:1827 +Man-o’-War:1827 +Elvish Piper:1825 +Imperial Recruiter:1810 +Sundering Titan:1806 +Decree of Justice:1803 +Prossh, Skyraider of Kher:1803 +Cloudblazer:1798 +Laquatus’s Champion:1795 +Darien, King of Kjeldor:1787 +Grenzo, Dungeon Warden:1787 +Pyroclasm:1787 +Brion Stoutarm:1786 +Utopia Sprawl:1785 +Counterspell:1772 +Coalition Relic:1765 +Disfigure:1755 +Kongming, “Sleeping Dragon”:1752 +Spikeshot Goblin:1752 +Blightning:1750 +Arbor Elf:1748 +Bident of Thassa:1743 +Hell’s Caretaker:1739 +Cultivate:1728 +Kindle:1726 +Luminarch Ascension:1719 +Fallen Angel:1718 +Krosan Tusker:1718 +Promise of Bunrei:1713 +Squadron Hawk:1712 +Mystic Snake:1711 +Horseshoe Crab:1707 +Ensnaring Bridge:1706 +Lorescale Coatl:1702 +Nicol Bolas:1702 +Boros Charm:1701 +Treasure Keeper:1701 +Undead Gladiator:1699 +Baloth Null:1698 +Chandra’s Outrage:1691 +Notion Thief:1691 +Merfolk Looter:1689 +Willbender:1689 +Azusa, Lost but Seeking:1686 +Quicksilver Dagger:1686 +Armageddon:1683 +Dusk Legion Zealot:1678 +Zombify:1678 +Urbis Protector:1676 +Rishadan Port:1673 +Blue Sun’s Zenith:1672 +Mesmeric Fiend:1669 +Chalice of the Void:1668 +Zulaport Cutthroat:1662 +Epic Confrontation:1658 +Exclude:1658 +Eidolon of the Great Revel:1655 +Nyx-Fleece Ram:1653 +Diabolic Edict:1651 +Brainstorm:1648 +Magus of the Wheel:1648 +Zada, Hedron Grinder:1645 +Court Hussar:1638 +Sift:1638 +Iwamori of the Open Fist:1637 +Twisted Abomination:1633 +Izzet Chemister:1632 +Ire Shaman:1629 +Kavu Predator:1628 +Street Wraith:1628 +Dauntless Cathar:1625 +Cloudshift:1622 +Mystic of the Hidden Way:1622 +Summoner’s Pact:1622 +Ball Lightning:1621 +Skeletonize:1620 +Ruthless Ripper:1614 +Hordeling Outburst:1609 +Path of Peace:1609 +Loyal Sentry:1607 +Eladamri’s Call:1606 +Mishra’s Factory:1604 +Ash Barrens:1602 +Griffin Protector:1591 +Myriad Landscape:1588 +Hanna, Ship’s Navigator:1586 +Flash:1585 +Prophetic Prism:1585 +Unearth:1584 +Enthralling Victor:1583 +Freed from the Real:1581 +Fathom Seer:1578 +Sai of the Shinobi:1578 +Ancient Craving:1577 +Bloodhunter Bat:1577 +Invigorate:1576 +Watchwolf:1575 +Mogg Flunkies:1571 +Vessel of Nascency:1571 +Whitemane Lion:1571 +Swiftfoot Boots:1570 +Plague Wind:1569 +Perilous Myr:1568 +Karona’s Zealot:1567 +Geist of the Moors:1563 +Jalira, Master Polymorphist:1563 +Cascade Bluffs:1560 +Elvish Aberration:1560 +Kavu Climber:1555 +Thresher Lizard:1555 +Horror of the Broken Lands:1551 +Ainok Survivalist:1549 +Genju of the Falls:1549 +Frenzied Goblin:1547 +Pyre Hound:1545 +Stangg:1544 +Twilight Mire:1544 +Broodhatch Nantuko:1542 +Kor Firewalker:1542 +Ratcatcher:1542 +Presence of Gond:1541 +Noble Templar:1539 +Brine Elemental:1537 +Death’s-Head Buzzard:1537 +Fierce Empath:1537 +Timberpack Wolf:1537 +Skirk Commando:1536 +Ghost Ship:1535 +Ember Weaver:1533 +Pact of Negation:1531 +Shoreline Ranger:1531 +Woolly Loxodon:1526 +Curiosity:1525 +Gods Willing:1523 +Deadly Designs:1521 +Phyrexian Ghoul:1519 +Giant Growth:1518 +Fortune Thief:1517 +Genju of the Spires:1517 +Angelic Page:1516 +Nettle Sentinel:1516 +Wildheart Invoker:1514 +Ambassador Oak:1513 +Nezumi Cutthroat:1511 +Knight of the Skyward Eye:1510 +Dark Ritual:1509 +Supernatural Stamina:1509 +Flooded Grove:1503 +Ordeal of Heliod:1503 +Fetid Heath:1500 +Accumulated Knowledge:1498 +Balduvian Horde:1497 +Vampire Lacerator:1491 +Chartooth Cougar:1487 +Lunarch Mantle:1487 +Pendelhaven:1487 +Doomsday:1486 +Colossal Dreadmaw:1485 +Krosan Colossus:1483 +Retraction Helix:1473 +Arcane Denial:1472 +Quicksand:1472 +Fencing Ace:1470 +Goblin War Drums:1467 +Self-Assembler:1463 +Rugged Prairie:1461 +Caustic Tar:1459 +Erg Raiders:1458 +Simian Spirit Guide:1458 +Regrowth:1454 +Mikokoro, Center of the Sea:1450 +Returned Phalanx:1449 +Cursecatcher:1445 +Tree of Redemption:1445 +Soulbright Flamekin:1444 +Primal Clay:1443 +Uncaged Fury:1443 +Will-o’-the-Wisp:1443 +Browbeat:1434 +Heavy Arbalest:1430 +Echoing Courage:1429 +Blood Moon:1425 +Choking Tethers:1424 +Stampede Driver:1422 +Crimson Mage:1421 +Relentless Rats:1421 +Living Wish:1420 +Totally Lost:1418 +Humble Defector:1417 +Ihsan’s Shade:1417 +Zoetic Cavern:1412 +Act of Treason:1405 +Savannah Lions:1404 +Coralhelm Guide:1398 +Trumpet Blast:1397 +Twisted Image:1397 +Dragon’s Eye Savants:1392 +Blue Elemental Blast:1385 +Ancient Stirrings:1377 +Phantasmal Bear:1374 +Rest in Peace:1373 +Dirge of Dread:1372 +Red Elemental Blast:1361 +Triskaidekaphobia:1361 +Cinder Storm:1352 +Auramancer:1346 +Haunted Fengraf:1343 +Strionic Resonator:1342 +Act of Heroism:1341 +Borrowing:100,000 Arrows 1338 +Jackal Pup:1337 +Valor in Akros:1337 +Nihil Spellbomb:1316 +Assembly-Worker:1301 +Pillage:1300 +Disenchant:1271 +Renewed Faith:1250 +Plummet:1238 +Congregate:1218 +Lull:1212 +Conflux:1208 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/rix.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/rix.csv new file mode 100644 index 0000000000..4d56154087 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/rix.csv @@ -0,0 +1,191 @@ +Rekindling Phoenix:2418 +Tetzimoc, Primal Death:2401 +Ravenous Chupacabra:2290 +Twilight Prophet:2282 +Etali, Primal Storm:2192 +Angrath, the Flame-Chained:2180 +The Immortal Sun:2168 +Profane Procession:2155 +Jadelight Ranger:2143 +Ghalta, Primal Hunger:2131 +Tendershoot Dryad:2121 +Bishop of Binding:2103 +Kumena, Tyrant of Orazca:2098 +Dire Fleet Poisoner:2094 +Trapjaw Tyrant:2087 +Bombard:2052 +Moment of Craving:2039 +Huatli, Radiant Champion:2029 +Hadana’s Climb:2019 +Reaver Ambush:2001 +Warkite Marauder:2001 +Champion of Dusk:2000 +Baffling End:1990 +Luminous Bonds:1970 +Impale:1966 +Golden Demise:1946 +Journey to Eternity:1941 +Crested Herdcaller:1936 +Azor, the Lawbringer:1914 +Thrashing Brontodon:1908 +Raging Regisaur:1902 +Zacama, Primal Calamity:1901 +Legion Lieutenant:1898 +Deeproot Elite:1893 +Sadistic Skymarcher:1893 +Needletooth Raptor:1889 +Elenda, the Dusk Rose:1888 +Dire Fleet Daredevil:1883 +Merfolk Mistbinder:1881 +Hunt the Weak:1839 +Forerunner of the Legion:1828 +Zetalpa, Primal Dawn:1820 +Golden Guardian:1819 +Radiant Destiny:1816 +Vona’s Hunger:1798 +Polyraptor:1793 +Tilonalli’s Summoner:1792 +Swift Warden:1774 +Slaughter the Strong:1767 +Protean Raider:1764 +Waterknot:1762 +Seafloor Oracle:1761 +Forerunner of the Empire:1760 +Divine Verdict:1759 +Reckless Rage:1758 +Dusk Legion Zealot:1755 +Squire’s Devotion:1754 +Temple Altisaur:1753 +Forerunner of the Heralds:1749 +Deadeye Brawler:1748 +Nezahal, Primal Tide:1742 +Captain’s Hook:1722 +Curious Obsession:1720 +Charging Tuskodon:1717 +Azor’s Gateway:1706 +Dire Fleet Neckbreaker:1703 +Wayward Swordtooth:1699 +Resplendent Griffin:1698 +Jungle Creeper:1693 +Siegehorn Ceratops:1690 +Kitesail Corsair:1689 +Martyr of Dusk:1689 +Exultant Skymarcher:1686 +Sailor of Means:1683 +Silvergill Adept:1680 +Atzocan Seer:1675 +Jungleborn Pioneer:1674 +Path of Discovery:1669 +Skymarcher Aspirant:1667 +Siren Reaver:1661 +Paladin of Atonement:1655 +Forerunner of the Coalition:1652 +Mutiny:1648 +Storm Fleet Sprinter:1638 +Relentless Raptor:1634 +Everdawn Champion:1625 +Goblin Trailblazer:1622 +Storm Fleet Swashbuckler:1606 +Spire Winder:1600 +Strength of the Pack:1594 +Secrets of the Golden City:1593 +Mausoleum Harpy:1586 +Slippery Scoundrel:1585 +Colossal Dreadmaw:1584 +Knight of the Stampede:1584 +Dusk Charger:1579 +Expel from Orazca:1578 +Oathsworn Vampire:1578 +Overgrown Armasaur:1576 +Daring Buccaneer:1562 +Deadeye Rig-Hauler:1557 +Sun-Crested Pterodon:1557 +Soul of the Rapids:1549 +Cherished Hatchling:1547 +Crashing Tide:1538 +Recover:1538 +Arch of Orazca:1537 +Majestic Heliopterus:1531 +Sanguine Glorifier:1525 +Form of the Dinosaur:1523 +Pride of Conquerors:1523 +Famished Paladin:1516 +Moment of Triumph:1515 +Silverclad Ferocidons:1511 +Frilled Deathspitter:1509 +Kumena’s Awakening:1505 +Snubhorn Sentry:1504 +Voracious Vampire:1504 +Fathom Fleet Boarder:1501 +Buccaneer’s Bravado:1492 +Thunderherd Migration:1487 +Legion Conquistador:1483 +See Red:1481 +Riverwise Augur:1478 +Cacophodon:1477 +Tomb Robber:1475 +Giltgrove Stalker:1472 +Swaggering Corsair:1472 +Evolving Wilds:1463 +Dinosaur Hunter:1461 +World Shaper:1452 +Path of Mettle:1447 +Hardy Veteran:1446 +Mist-Cloaked Herald:1443 +Fanatical Firebrand:1442 +Jadecraft Artisan:1440 +Stampeding Horncrest:1439 +Admiral’s Order:1436 +Timestream Navigator:1433 +Brazen Freebooter:1427 +Imperial Ceratops:1415 +Aggressive Urge:1413 +Traveler’s Amulet:1412 +Grasping Scoundrel:1403 +Jade Bearer:1384 +Aquatic Incursion:1375 +Shake the Foundations:1374 +Vampire Revenant:1368 +Orazca Raptor:1363 +Sun Sentinel:1362 +Hornswoggle:1350 +Mastermind’s Acquisition:1344 +Raptor Companion:1340 +Sea Legs:1332 +Sun-Collared Raptor:1322 +Tilonalli’s Crown:1318 +Gleaming Barrier:1307 +Enter the Unknown:1301 +Storm the Vault:1297 +Crafty Cutpurse:1291 +Pitiless Plunderer:1288 +Forsaken Sanctuary:1281 +Pirate’s Pillage:1274 +Arterial Flow:1255 +Woodland Stream:1246 +Orazca Frillback:1244 +Dead Man’s Chest:1233 +River Darter:1233 +Naturalize:1224 +Cleansing Ray:1203 +Highland Lake:1199 +Strider Harness:1198 +Negate:1195 +Stone Quarry:1192 +Dark Inquiry:1187 +Release to the Wind:1165 +Plummet:1160 +Foul Orchard:1146 +Orazca Relic:1123 +Flood of Recollection:1121 +Canal Monitor:1094 +Blazing Hope:1069 +Brass’s Bounty:1064 +Sworn Guardian:1060 +Blood Sun:1059 +Gruesome Fate:1036 +Awakened Amalgam:1017 +Induced Amnesia:1003 +Silent Gravestone:968 +Sphinx’s Decree:961 +Shatter:907 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/setsWithRatings.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/setsWithRatings.csv new file mode 100644 index 0000000000..172ed6537e --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/setsWithRatings.csv @@ -0,0 +1,19 @@ +# this file specifies which sets have set files. +# each line must be exactly the 3 letter expansion code. this corresponds to a csv resource file in the same directory +# The .csv files have a strict format: +# each line must be: +# cardname : integer rating +# each set's ratings are post-processed to have a normalized score [1..100], so the files don't need to have the same rating system. +# I created the first few files with draftaholicsanonymous but you can use any integer rating system you want +grn +m19 +dom +rix +xln +hou +akh +aer +kld +mm3 +ima +m13 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/xln.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/xln.csv new file mode 100644 index 0000000000..3e92060d88 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/xln.csv @@ -0,0 +1,259 @@ +Vraska, Relic Seeker:2381 +Hostage Taker:2336 +Carnage Tyrant:2332 +Regisaur Alpha:2276 +Ripjaw Raptor:2228 +Captivating Crew:2225 +Vraska’s Contempt:2214 +Vona, Butcher of Magan:2192 +Huatli, Warrior Poet:2173 +Repeating Barrage:2144 +Charging Monstrosaur:2133 +Lightning Strike:2122 +Walk the Plank:2096 +Ixalan’s Binding:2083 +Burning Sun’s Avatar:2068 +Mavren Fein, Dusk Apostle:2061 +Settle the Wreckage:2057 +Waker of the Wilds:2033 +Kinjalli’s Sunwing:2032 +Sanctum Seeker:2003 +Rampaging Ferocidon:2000 +Legion’s Landing:1999 +Territorial Hammerskull:1990 +Dreamcaller Siren:1983 +Bishop of Rebirth:1975 +Vanquish the Weak:1969 +River’s Rebuke:1967 +Fathom Fleet Captain:1950 +Imperial Aerosaur:1939 +Drover of the Mighty:1932 +Deathgorge Scavenger:1917 +Snapping Sailback:1916 +Shapers of Nature:1913 +Entrancing Melody:1911 +Contract Killing:1910 +Adanto Vanguard:1901 +Air Elemental:1901 +Dire Fleet Ravager:1889 +Merfolk Branchwalker:1889 +Jace, Cunning Castaway:1881 +Savage Stomp:1878 +Kitesail Freebooter:1877 +Raging Swordtooth:1858 +Ruin Raider:1856 +Vance’s Blasting Cannons:1854 +Unfriendly Fire:1844 +Captain Lannery Storm:1843 +Pious Interdiction:1842 +Firecannon Blast:1837 +Ranging Raptors:1835 +Treasure Map:1832 +Sky Terror:1824 +Vanquisher’s Banner:1823 +Watertrap Weaver:1811 +Pirate’s Cutlass:1806 +Emperor’s Vanguard:1805 +Storm Fleet Aerialist:1805 +Tempest Caller:1798 +Daring Saboteur:1795 +Search for Azcanta:1794 +Rowdy Crew:1793 +Seekers’ Squire:1777 +Skulduggery:1773 +Glorifier of Dusk:1757 +Siren Lookout:1757 +One With the Wind:1754 +Admiral Beckett Brass:1752 +Bishop of the Bloodstained:1752 +Wanted Scoundrels:1750 +Pounce:1748 +Jade Guardian:1740 +Vineshaper Mystic:1740 +Skymarch Bloodletter:1739 +Gishath, Sun’s Avatar:1733 +Call to the Feast:1730 +Paladin of the Bloodstained:1729 +Emissary of Sunrise:1725 +Otepec Huntmaster:1719 +Thundering Spineback:1710 +Tishana’s Wayfinder:1707 +Fiery Cannonade:1697 +Verdant Sun’s Avatar:1692 +Dark Nourishment:1682 +Deadeye Tracker:1679 +Siren Stormtamer:1679 +Chart a Course:1674 +Dire Fleet Captain:1673 +Inspiring Cleric:1671 +Bishop’s Soldier:1669 +Deathless Ancient:1669 +Deeproot Warrior:1669 +Tilonalli’s Knight:1669 +Deadeye Plunderers:1664 +Conqueror’s Galleon:1657 +Bright Reprisal:1654 +Shining Aerosaur:1654 +Raptor Hatchling:1653 +Wakening Sun’s Avatar:1651 +Fell Flagship:1649 +Herald of Secret Streams:1645 +Headstrong Brute:1643 +Fathom Fleet Firebrand:1641 +Colossal Dreadmaw:1637 +Vicious Conquistador:1636 +Bloodcrazed Paladin:1635 +Bellowing Aegisaur:1629 +Tishana, Voice of Thunder:1628 +Kopala, Warden of Waves:1626 +New Horizons:1624 +Deadeye Tormentor:1621 +Marauding Looter:1621 +Kumena’s Speaker:1619 +Vampire’s Zeal:1618 +Duskborne Skymarcher:1616 +Ixalli’s Diviner:1616 +Ravenous Daggertooth:1615 +Angrath’s Marauders:1613 +Perilous Voyage:1613 +Slash of Talons:1613 +Shaper Apprentice:1612 +Wildgrowth Walker:1609 +Storm Fleet Spy:1607 +Sailor of Means:1605 +Bonded Horncrest:1600 +Grazing Whiptail:1597 +Thaumatic Compass:1596 +Thrash of Raptors:1594 +Legion’s Judgment:1591 +Queen’s Commission:1590 +Deeproot Champion:1587 +Steadfast Armasaur:1581 +River Heralds’ Boon:1579 +Rigging Runner:1575 +Goring Ceratops:1572 +Skittering Heartstopper:1572 +Storm Fleet Arsonist:1571 +Dire Fleet Hoarder:1569 +Commune with Dinosaurs:1566 +Atzocan Archer:1562 +River Sneak:1562 +Skyblade of the Legion:1560 +Run Aground:1558 +Anointed Deacon:1557 +Pterodon Knight:1557 +Mark of the Vampire:1555 +Fathom Fleet Cutthroat:1552 +Prosperous Pirates:1549 +Shipwreck Looter:1546 +Arguel’s Blood Fast:1536 +Wind Strider:1535 +Legion Conquistador:1533 +Depths of Desire:1531 +Ruthless Knave:1531 +Sunbird’s Invocation:1531 +Growing Rites of Itlimoc:1525 +Lookout’s Dispersal:1525 +Lightning-Rig Crew:1517 +Sure Strike:1517 +Boneyard Parley:1515 +Dusk Legion Dreadnought:1515 +Priest of the Wakening Sun:1514 +Brazen Buccaneers:1513 +Star of Extinction:1513 +Raptor Companion:1511 +Rallying Roar:1505 +Heartless Pillage:1501 +Sleek Schooner:1500 +Fleet Swallower:1498 +Ixalli’s Keeper:1497 +Dive Down:1496 +Sheltering Light:1492 +Sun-Crowned Hunters:1483 +Cobbled Wings:1474 +Dire Fleet Interloper:1473 +Lurking Chupacabra:1465 +Storm Fleet Pyromancer:1463 +Dowsing Dagger:1456 +Shadowed Caravel:1455 +Spike-Tailed Ceratops:1455 +Kinjalli’s Caller:1454 +Deeproot Waters:1452 +Rootbound Crag:1451 +Verdant Rebirth:1451 +Storm Sculptor:1448 +Frenzied Raptor:1446 +Opt:1440 +Jungle Delver:1438 +Sword-Point Diplomacy:1438 +Nest Robber:1436 +Tilonalli’s Skinshifter:1434 +Siren’s Ruse:1433 +Crushing Canopy:1431 +Dinosaur Stampede:1429 +Overflowing Insight:1425 +Swashbuckling:1418 +Crash the Ramparts:1413 +Sunpetal Grove:1412 +Favorable Winds:1406 +Shapers’ Sanctuary:1406 +Queen’s Bay Soldier:1405 +Deadeye Quartermaster:1401 +Queen’s Agent:1397 +Dual Shot:1396 +Pirate’s Prize:1394 +March of the Drowned:1387 +Blossom Dryad:1385 +Drowned Catacomb:1383 +Tocatli Honor Guard:1373 +Dragonskull Summit:1372 +Raiders’ Wake:1371 +Spell Swindle:1368 +Sunrise Seeker:1361 +Desperate Castaways:1342 +Prying Blade:1338 +Sorcerous Spyglass:1334 +Blight Keeper:1330 +Costly Plunder:1310 +Primal Amulet:1306 +Unclaimed Territory:1306 +Fire Shrine Keeper:1301 +Imperial Lancer:1297 +Belligerent Brontodon:1296 +Emergent Growth:1293 +Wily Goblin:1293 +Cancel:1287 +Duress:1286 +Old-Growth Dryads:1282 +Navigator’s Ruin:1273 +Glacial Fortress:1262 +Trove of Temptation:1259 +Pillar of Origins:1252 +Hijack:1236 +Rile:1234 +Revel in Riches:1232 +Headwater Sentries:1225 +Grim Captain’s Call:1214 +Elaborate Firecannon:1209 +Looming Altisaur:1206 +Encampment Keeper:1199 +Slice in Twain:1198 +Spell Pierce:1186 +Makeshift Munitions:1183 +Rummaging Goblin:1182 +Axis of Mortality:1179 +Unknown Shores:1173 +Shore Keeper:1172 +Ancient Brontodon:1165 +Sanguine Sacrament:1162 +Arcane Adaptation:1151 +Ashes of the Abhorrent:1135 +Ritual of Rejuvenation:1102 +Field of Ruin:1097 +Hierophant’s Chalice:1077 +Gilded Sentinel:1035 +Blinding Fog:1033 +Demystify:1023 +Sentinel Totem:998 +Demolish:994 +Spreading Rot:935 \ No newline at end of file From 6f93abfd5ad7f4dd3630f2eab093cb62ddd546f5 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 28 Oct 2018 14:23:53 -0700 Subject: [PATCH 090/167] ai ratings revamp code review changes * when resources are missing, fails gracefully * uses highest found rating, rather than most recently found for the case of sets containing duplicates * moved ratings files to their own directory * thread safe reading of all files --- .../java/mage/player/ai/utils/RateCard.java | 56 +- .../src/main/resources/ratings.txt | 1214 ----------------- .../src/main/resources/{ => ratings}/aer.csv | 0 .../src/main/resources/{ => ratings}/akh.csv | 0 .../src/main/resources/{ => ratings}/dom.csv | 0 .../src/main/resources/{ => ratings}/grn.csv | 0 .../src/main/resources/{ => ratings}/hou.csv | 0 .../src/main/resources/{ => ratings}/ima.csv | 0 .../src/main/resources/{ => ratings}/kld.csv | 0 .../src/main/resources/{ => ratings}/m13.csv | 0 .../src/main/resources/{ => ratings}/m19.csv | 0 .../src/main/resources/{ => ratings}/mm3.csv | 0 .../src/main/resources/{ => ratings}/rix.csv | 0 .../{ => ratings}/setsWithRatings.csv | 3 +- .../src/main/resources/{ => ratings}/xln.csv | 0 15 files changed, 41 insertions(+), 1232 deletions(-) delete mode 100644 Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings.txt rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/aer.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/akh.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/dom.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/grn.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/hou.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/ima.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/kld.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/m13.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/m19.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/mm3.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/rix.csv (100%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/setsWithRatings.csv (98%) rename Mage.Server.Plugins/Mage.Player.AI/src/main/resources/{ => ratings}/xln.csv (100%) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index 4d488be4c9..b31894e48c 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -49,6 +49,9 @@ public final class RateCard { private static final int DEFAULT_NOT_RATED_UNCOMMON_RATING = 60; private static final int DEFAULT_NOT_RATED_RARE_RATING = 75; private static final int DEFAULT_NOT_RATED_MYTHIC_RATING = 90; + + private static String RATINGS_DIR = "/ratings/"; + private static String RATINGS_SET_LIST = RATINGS_DIR + "setsWithRatings.csv"; private static final Logger log = Logger.getLogger(RateCard.class); @@ -163,17 +166,7 @@ public final class RateCard { * @return Rating number from [1:100]. */ public static int getCardRating(Card card) { - if (setsWithRatingsToBeLoaded == null){ - setsWithRatingsToBeLoaded = new LinkedList<>(); - InputStream is = RateCard.class.getResourceAsStream("/setsWithRatings.csv"); - Scanner scanner = new Scanner(is); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - if (line.substring(0,1) != "#"){ - setsWithRatingsToBeLoaded.add(line); - } - } - } + readRatingSetList(); String exp = card.getExpansionSetCode().toLowerCase(); readRatings(exp); @@ -193,22 +186,47 @@ public final class RateCard { } return DEFAULT_NOT_RATED_CARD_RATING; } + + /** + * reads the list of sets that have ratings csv files + * populates the setsWithRatingsToBeLoaded + */ + private synchronized static void readRatingSetList(){ + try { + if (setsWithRatingsToBeLoaded == null){ + setsWithRatingsToBeLoaded = new LinkedList<>(); + InputStream is = RateCard.class.getResourceAsStream(RATINGS_SET_LIST); + Scanner scanner = new Scanner(is); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (!line.substring(0,1).equals("#")){ + setsWithRatingsToBeLoaded.add(line); + } + } + } + }catch (Exception e) { + log.info("failed to read ratings set list file: " + RATINGS_SET_LIST ); + e.printStackTrace(); + } + } /** - * Reads ratings from resources. + * Reads ratings from resources and loads them into ratings map */ private synchronized static void readRatings(String expCode) { if (ratings == null) { ratings = new HashMap<>(); } if (setsWithRatingsToBeLoaded.contains(expCode)){ - System.out.println("reading draftbot ratings for the set" + expCode); - readFromFile("/" + expCode + ".csv"); + log.info("reading draftbot ratings for the set" + expCode); + readFromFile(RATINGS_DIR + expCode + ".csv"); setsWithRatingsToBeLoaded.remove(expCode); } } - - private static void readFromFile(String path) { + /** + * reads ratings from the file + */ + private synchronized static void readFromFile(String path) { Integer min = Integer.MAX_VALUE, max = 0; Map thisFileRatings = new HashMap<>(); try { @@ -233,9 +251,13 @@ public final class RateCard { for (String name: thisFileRatings.keySet()){ int r = thisFileRatings.get(name); int newrating = (int)(100.0f * (r - min) / (max - min)); - ratings.put(name, newrating); + if (!ratings.containsKey(name) || + (ratings.containsKey(name) && newrating > ratings.get(name)) ){ + ratings.put(name, newrating); + } } } catch (Exception e) { + log.info("failed to read ratings file: " + path ); e.printStackTrace(); } } diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings.txt b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings.txt deleted file mode 100644 index 6ccb175ffb..0000000000 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings.txt +++ /dev/null @@ -1,1214 +0,0 @@ -1569 : Day of Judgment -1548 : Garruk Wildspeaker -1547 : Sword of Vengeance -1544 : Baneslayer Angel -1533 : Kargan Dragonlord -1526 : Frost Titan -1523 : Wurmcoil Engine -1522 : Ob Nixilis, the Fallen -1520 : Chandra Nalaar -1516 : Gideon Jura -1516 : Primeval Titan -1513 : Ajani Goldmane -1512 : Basilisk Collar -1511 : Vampire Nighthawk -1511 : Skithiryx, the Blight Dragon -1509 : Serra Angel -1508 : Koth of the Hammer -1507 : Jace, the Mind Sculptor -1507 : Avenger of Zendikar -1506 : Vengevine -1505 : Nissa Revane -1502 : Student of Warfare -1501 : Jace Beleren -1500 : Iona, Shield of Emeria -1500 : Glimmerpost -1500 : Transcendent Master -1500 : Guul Draz Assassin -1500 : Kozilek, Butcher of Truth -1500 : Omnath, Locus of Mana -1500 : Abyssal Persecutor -1500 : Dragonmaster Outcast -1500 : Kazuul, Tyrant of the Cliffs -1500 : Anowon, the Ruin Sage -1500 : Platinum Angel -1499 : Eldrazi Conscription -1499 : Drana, Kalastria Bloodchief -1499 : Conquering Manticore -1498 : Mul Daya Channelers -1498 : Lord of Shatterskull Pass -1498 : Admonition Angel -1498 : Archon of Redemption -1498 : Inferno Titan -1497 : Sorin Markov -1497 : Sword of Body and Mind -1496 : Terra Stomper -1496 : Carnifex Demon -1496 : Deathless Angel -1495 : Linvala, Keeper of Silence -1492 : Bloodghast -1492 : Steel Hellkite -1491 : Obsidian Fireheart -1489 : Guul Draz Specter -1489 : Kazandu Tuskcaller -1488 : Emrakul, the Aeons Torn -1488 : Coralhelm Commander -1488 : Wrexial, the Risen Deep -1487 : Nirkana Revenant -1486 : Scalding Tarn -1486 : Sphinx of Jwar Isle -1486 : Khalni Hydra -1485 : Felidar Sovereign -1485 : Halo Hunter -1485 : Sarkhan the Mad -1485 : Consume the Meek -1484 : Rampaging Baloths -1484 : Gigantiform -1483 : Consuming Vapors -1482 : It That Betrays -1481 : Eldrazi Monument -1481 : All Is Dust -1480 : Kalitas, Bloodchief of Ghet -1480 : Mimic Vat -1480 : Pestilence Demon -1480 : Stirring Wildwood -1480 : Mind Control -1479 : Comet Storm -1477 : Creeping Tar Pit -1476 : Harabaz Druid -1475 : Geth, Lord of the Vault -1475 : Pelakka Wurm -1473 : Lorthos, the Tidemaker -1473 : Elspeth Tirel -1473 : Grave Titan -1472 : Celestial Colonnade -1471 : Bear Umbra -1471 : Triskelion -1469 : Turntimber Ranger -1468 : Terastodon -1466 : Kazuul Warlord -1465 : Sphinx of Magosi -1464 : Luminarch Ascension -1464 : Lighthouse Chronologist -1464 : Stone Idol Trap -1464 : Chain Reaction -1463 : Sunblast Angel -1463 : Spawnsire of Ulamog -1463 : Royal Assassin -1462 : Misty Rainforest -1461 : Jwari Shapeshifter -1460 : Hellcarver Demon -1459 : Hellkite Charger -1459 : Rite of Replication -1458 : Eternity Vessel -1458 : Bala Ged Thief -1458 : Kalastria Highborn -1458 : Fireball -1456 : Precursor Golem -1456 : Venser, the Sojourner -1456 : Joraga Treespeaker -1456 : Wolfbriar Elemental -1456 : Mitotic Slime -1455 : Journey to Nowhere -1454 : Strata Scythe -1452 : Awakening Zone -1452 : Magmaw -1452 : Gaea's Revenge -1449 : Ezuri's Brigade -1448 : Strength of the Tajuru -1448 : Nantuko Shade -1446 : Ratchet Bomb -1445 : Sun Titan -1444 : Hand of the Praetors -1443 : Lotus Cobra -1441 : Nim Deathmantle -1440 : Arid Mesa -1439 : Scute Mob -1439 : Mystifying Maze -1437 : Argentum Armor -1436 : Chimeric Mass -1434 : Magma Phoenix -1433 : Chandra Ablaze -1433 : Scars of Mirrodin -1433 : Rise of the Eldrazi -1433 : Brittle Effigy -1432 : Blade of the Bloodchief -1432 : Oracle of Mul Daya -1432 : Kuldotha Phoenix -1432 : Mordant Dragon -1431 : Myr Battlesphere -1431 : Skinrender -1431 : Argent Sphinx -1431 : Talus Paladin -1430 : Vengeful Archon -1428 : Cunning Sparkmage -1426 : Celestial Mantle -1425 : Roil Elemental -1425 : Malakir Bloodwitch -1425 : Contagion Clasp -1424 : Trusty Machete -1424 : Sea Gate Loremaster -1424 : World Queller -1423 : Burst Lightning -1423 : Agadeem Occultist -1422 : Raging Ravine -1422 : Fauna Shaman -1421 : Valakut, the Molten Pinnacle -1421 : Seer's Sundial -1420 : Butcher of Malakir -1415 : Novablast Wurm -1414 : Liliana Vess -1413 : Marsh Flats -1412 : Obstinate Baloth -1412 : Condemn -1409 : Emeria Angel -1408 : Sphinx of Lost Truths -1408 : Goliath Sphinx -1407 : Kazandu Blademaster -1407 : Verdant Catacombs -1406 : Grasp of Darkness -1406 : Marshal's Anthem -1404 : Platinum Emperion -1404 : Doom Blade -1404 : Lightning Bolt -1403 : Grappling Hook -1403 : Ulamog, the Infinite Gyre -1402 : Conundrum Sphinx -1400 : Momentous Fall -1400 : Protean Hydra -1399 : Ancient Hellkite -1398 : Flame Slash -1396 : Kabira Evangel -1396 : Pacifism -1395 : Gelatinous Genesis -1394 : Arc Trail -1393 : Joraga Warcaller -1392 : Lavaclaw Reaches -1392 : Lodestone Golem -1390 : Liege of the Tangle -1389 : Grand Architect -1386 : Trigon of Corruption -1386 : Angelic Arbiter -1383 : True Conviction -1383 : Mox Opal -1383 : Spikeshot Elder -1380 : Devout Lightcaster -1379 : Gatekeeper of Malakir -1378 : Gigantomancer -1377 : Shepherd of the Lost -1375 : Bloodchief Ascension -1375 : Darksteel Axe -1375 : Livewire Lash -1372 : Hoarding Dragon -1368 : Darksteel Juggernaut -1367 : Conqueror's Pledge -1367 : Arrest -1367 : Pyroclasm -1364 : Galvanic Blast -1363 : Lux Cannon -1362 : Echo Mage -1361 : Quicksilver Gargantuan -1360 : Razor Hippogriff -1360 : Volition Reins -1360 : Rage Nimbus -1360 : Tuktuk the Explorer -1357 : Putrefax -1353 : Prototype Portal -1353 : Disaster Radius -1353 : Prodigal Pyromancer -1352 : Staggershock -1352 : Brimstone Mage -1351 : Punishing Fire -1348 : Rapacious One -1346 : Golem Artisan -1345 : Air Servant -1343 : Goblin Guide -1342 : Overwhelming Stampede -1342 : Cudgel Troll -1336 : Emeria, the Sky Ruin -1335 : Stoneforge Mystic -1334 : Engulfing Slagwurm -1333 : Kemba, Kha Regent -1332 : Etched Champion -1324 : Beastmaster Ascension -1324 : Warren Instigator -1315 : Plated Geopede -1315 : Kabira Vindicator -1315 : Chandra's Outrage -1313 : Oxidda Scrapmelter -1312 : Hideous End -1312 : Hedron Matrix -1312 : Blinding Mage -1311 : Slice in Twain -1311 : Knight Exemplar -1309 : Reassembling Skeleton -1308 : Embersmith -1308 : Hellion Eruption -1305 : Dispense Justice -1304 : Turn to Slag -1304 : Boar Umbra -1302 : Ulamog's Crusher -1299 : Artisan of Kozilek -1297 : Hada Freeblade -1296 : Eye of Ugin -1296 : Death's Shadow -1295 : Marsh Casualties -1295 : Kor Skyfisher -1294 : Summoning Trap -1293 : Smother -1292 : Howling Banshee -1290 : Domestication -1290 : Urge to Feed -1289 : Lightkeeper of Emeria -1287 : Demon of Death's Gate -1286 : Sylvok Replica -1286 : Vendetta -1284 : Broodwarden -1282 : Shatter -1281 : Asceticism -1280 : Assassinate -1279 : Cyclops Gladiator -1276 : Nomads' Assembly -1276 : Knight of Cliffhaven -1275 : Bestial Menace -1272 : Myrsmith -1272 : Necrotic Ooze -1272 : Aether Adept -1270 : Living Tsunami -1267 : Beastbreaker of Bala Ged -1264 : Adventuring Gear -1264 : Revoke Existence -1263 : Vampire Hexmage -1262 : Heavy Arbalest -1261 : Pathrazer of Ulamog -1260 : Disfigure -1258 : Forked Bolt -1258 : Stormfront Pegasus -1256 : Birds of Paradise -1253 : Nirkana Cutthroat -1253 : Voyager Drake -1251 : Heat Ray -1250 : Rust Tick -1250 : Crystal Ball -1248 : Windrider Eel -1245 : Acid Web Spider -1243 : Enclave Cryptologist -1238 : Myr Propagator -1238 : Kozilek's Predator -1237 : Vapor Snare -1236 : Steppe Lynx -1236 : Tempered Steel -1235 : Terminate -1234 : Palladium Myr -1234 : Tomb Hex -1234 : Garruk's Packleader -1233 : Electropotence -1231 : Black Knight -1230 : Narcolepsy -1229 : Acidic Slime -1226 : Oblivion Ring -1223 : Cystbearer -1221 : Rusted Relic -1221 : Azure Drake -1220 : Venerated Teacher -1220 : Splinter Twin -1220 : Searing Blaze -1219 : Tideforce Elemental -1218 : Trinket Mage -1218 : Whispersilk Cloak -1216 : Hada Spy Patrol -1216 : Jace's Ingenuity -1215 : Kor Aeronaut -1214 : Cerebral Eruption -1214 : Nest Invader -1214 : Water Servant -1213 : World at War -1212 : Bladetusk Boar -1211 : Traitorous Instinct -1210 : Plague Stinger -1210 : Ondu Giant -1210 : Cloud Crusader -1209 : Honor of the Pure -1207 : Barrage Ogre -1207 : Wall of Omens -1207 : Path to Exile -1206 : Umara Raptor -1206 : Mana Leak -1205 : Overgrown Battlement -1205 : Caustic Crawler -1205 : Behemoth Sledge -1203 : Growth Spasm -1202 : Bellowing Tanglewurm -1200 : Flesh Allergy -1199 : Cloud Elemental -1198 : Darkslick Drake -1198 : Quag Sickness -1197 : Myr Galvanizer -1195 : Barbed Battlegear -1195 : Assault Griffin -1193 : Foresee -1192 : Induce Despair -1192 : Greater Basilisk -1191 : Bloodhusk Ritualist -1189 : Leatherback Baloth -1188 : Kor Spiritdancer -1188 : Rise from the Grave -1187 : Kor Hookmaster -1187 : Sleep -1185 : Grafted Exoskeleton -1185 : Skywatcher Adept -1183 : Glimmerpoint Stag -1182 : Kuldotha Forgemaster -1182 : Mortician Beetle -1181 : Eldrazi Temple -1180 : Harrow -1178 : Ezuri, Renegade Leader -1175 : Hammer of Ruin -1172 : Contagious Nim -1169 : Cultivate -1168 : Mindbreak Trap -1168 : Pitfall Trap -1168 : Inferno Trap -1167 : Turntimber Basilisk -1167 : Ember Hauler -1166 : Martial Coup -1164 : Perilous Myr -1163 : Iona's Judgment -1163 : Child of Night -1161 : Painsmith -1161 : Ogre's Cleaver -1161 : Finest Hour -1160 : Myr Reservoir -1160 : Duskdale Wurm -1160 : Elspeth, Knight-Errant -1159 : Garruk's Companion -1158 : Horizon Drake -1157 : Emrakul's Hatcher -1157 : Jagwasp Swarm -1156 : Thought Gorger -1156 : Guard Gomazoa -1156 : Last Kiss -1155 : Thada Adel, Acquisitor -1154 : Quest for the Gravelord -1154 : Destructive Force -1154 : Armored Ascension -1153 : Trigon of Rage -1153 : Join the Ranks -1153 : Sylvan Ranger -1152 : Merfolk Seastalkers -1152 : Merfolk Skyscout -1152 : Kor Firewalker -1151 : Elvish Archdruid -1149 : Sadistic Sacrament -1149 : Glint Hawk -1148 : Predatory Urge -1148 : Liliana's Specter -1148 : Woolly Thoctar -1147 : Stonework Puma -1146 : Archive Trap -1146 : Wild Griffin -1146 : Llanowar Elves -1145 : Necrogen Scudder -1144 : Armament Master -1143 : Keening Stone -1141 : Blazing Torch -1141 : Dawnglare Invoker -1140 : Torch Slinger -1140 : Geyser Glider -1140 : Fire Servant -1138 : Heartstabber Mosquito -1138 : Caravan Escort -1138 : Wildheart Invoker -1137 : Welkin Tern -1137 : Squadron Hawk -1137 : Maelstrom Pulse -1136 : Throne of Geth -1136 : Bloodbraid Elf -1135 : Glint Hawk Idol -1135 : Trigon of Infestation -1135 : Clone -1135 : Putrid Leech -1134 : Giant Scorpion -1134 : Ajani Vengeant -1133 : Grazing Gladehart -1132 : Cosi's Trickster -1131 : Juggernaut -1130 : Hedron Crab -1130 : Into the Roil -1130 : Ichor Rats -1130 : Ogre Geargrabber -1129 : Lightning Helix -1128 : Oust -1127 : Act of Treason -1126 : Arrow Volley Trap -1126 : Vedalken Certarch -1126 : Deathforge Shaman -1126 : Bituminous Blast -1125 : Training Grounds -1124 : Mark of Mutiny -1124 : Knight of the White Orchid -1123 : Tumble Magnet -1121 : Lumengrid Drake -1121 : Necropede -1121 : Yavimaya Wurm -1120 : Noble Hierarch -1119 : River Boa -1119 : Scrapdiver Serpent -1119 : Renegade Doppelganger -1119 : Tajuru Preserver -1119 : White Knight -1119 : Vengeful Rebirth -1118 : Mindslaver -1118 : Genesis Wave -1118 : Frostwind Invoker -1118 : Ranger of Eos -1118 : Sarkhan Vol -1117 : Corrupt -1117 : Chandra's Spitfire -1116 : Bonds of Quicksilver -1115 : Surrakar Marauder -1114 : Explorer's Scope -1114 : Ice Cage -1114 : Steel Overseer -1114 : Earthquake -1113 : Vines of Vastwood -1113 : Strider Harness -1113 : Snapping Drake -1112 : Drake Umbra -1112 : Warlord's Axe -1111 : Sphinx of the Steel Wind -1110 : Hand of Emrakul -1109 : Aether Figment -1109 : Hagra Diabolist -1109 : Murasa Pyromancer -1107 : Apex Hawks -1107 : Dead Reckoning -1104 : Guul Draz Vampire -1104 : Overrun -1104 : Battlegrace Angel -1103 : Elvish Visionary -1102 : Goblin Ruinblaster -1102 : Smite -1099 : Graypelt Hunter -1099 : Rhox War Monk -1099 : Stun Sniper -1098 : Khalni Heart Expedition -1098 : Aven Squire -1097 : Greenweaver Druid -1097 : Broodmate Dragon -1096 : Goblin Bushwhacker -1096 : Riddlesmith -1096 : Steady Progress -1096 : Blight Mamba -1096 : Pawn of Ulamog -1094 : Spined Wurm -1094 : Glacial Fortress -1094 : Master of the Wild Hunt -1091 : Blood Seeker -1091 : Carapace Forger -1090 : Highland Berserker -1090 : Phylactery Lich -1089 : Skeletal Wurm -1089 : Refraction Trap -1089 : Tattered Drake -1087 : Tainted Strike -1087 : Lorescale Coatl -1087 : Sprouting Thrinax -1086 : Arbor Elf -1085 : Frontier Guide -1085 : Sign in Blood -1084 : Mammoth Umbra -1084 : Rakka Mar -1083 : Air Elemental -1082 : Madrush Cyclops -1080 : Preordain -1080 : Ant Queen -1080 : Fiery Fall -1078 : Ichorclaw Myr -1076 : Gomazoa -1076 : Horizon Spellbomb -1076 : War Priest of Thune -1076 : Scroll Thief -1075 : Might of Oaks -1074 : Hellfire Mongrel -1074 : Kor Cartographer -1074 : Kor Sanctifiers -1074 : Champion's Drake -1074 : Darklit Gargoyle -1074 : Knight of the Reliquary -1073 : Fledgling Griffin -1072 : Goblin Shortcutter -1072 : Infiltration Lens -1072 : Indomitable Archangel -1071 : Bogardan Hellkite -1071 : Kathari Remnant -1070 : See Beyond -1070 : Ethersworn Adjudicator -1069 : Deny Reality -1069 : Vampire Aristocrat -1069 : Ethercaste Knight -1068 : Bladed Pinions -1068 : Kemba's Skyguard -1068 : AEther Figment -1067 : Tajuru Archer -1067 : Tuktuk Grunts -1067 : Stoic Rebuttal -1067 : Auriok Edgewright -1067 : Great Sable Stag -1066 : Tangle Angler -1066 : Barony Vampire -1066 : Druid of the Anima -1065 : Court Archers -1064 : Mold Shambler -1064 : Feast of Blood -1064 : Ondu Cleric -1064 : Deadly Recluse -1064 : Thornling -1063 : Paralyzing Grasp -1063 : Aura Gnarlid -1062 : Zektar Shrine Expedition -1062 : Blood Tribute -1062 : Bleak Coven Vampires -1061 : Rafiq of the Many -1061 : Nulltread Gargantuan -1060 : Baloth Cage Trap -1060 : Loam Lion -1060 : Stormtide Leviathan -1060 : Ball Lightning -1059 : Spawning Breath -1059 : Shoreline Salvager -1059 : Jenara, Asura of War -1058 : Halt Order -1058 : Stabbing Pain -1056 : Courier's Capsule -1056 : Shock -1055 : Khalni Gem -1055 : Disperse -1055 : Sigiled Paladin -1054 : Timbermaw Larva -1054 : Puncturing Light -1054 : Canopy Cover -1053 : Windborne Charge -1053 : Lightmine Field -1053 : Reverberate -1052 : Crypt Ripper -1052 : Looming Shade -1051 : Spire Barrage -1051 : Cadaver Imp -1050 : Summoner's Bane -1050 : Perimeter Captain -1049 : Makindi Griffin -1048 : Lullmage Mentor -1048 : Primal Bellow -1048 : Surrakar Spellblade -1048 : Awakener Druid -1048 : Conquerors Pledge -1047 : Mind Sludge -1047 : Neurok Replica -1047 : Neurok Invisimancer -1047 : Trigon of Thought -1047 : Kitesail -1047 : Wild Nacatl -1046 : Reckless Scholar -1046 : Sky Ruin Drake -1046 : Grindclock -1046 : Explore -1045 : Nissa's Chosen -1045 : Flameborn Hellion -1045 : Ghalma's Warden -1045 : Berserkers of Blood Ridge -1045 : Goblin Outlander -1044 : Virulent Swipe -1044 : Time of Heroes -1044 : Nightwing Shade -1044 : Scarland Thrinax -1043 : Time Warp -1043 : Rhox Pikemaster -1042 : Zendikar -1042 : Lavaball Trap -1042 : Magma Rift -1042 : Snake Umbra -1042 : Giant Spider -1041 : Shatterskull Giant -1041 : Cliff Threader -1041 : Sea Gate Oracle -1041 : Nemesis Trap -1041 : Rootbound Crag -1040 : Auriok Sunchaser -1040 : Corpse Cur -1040 : Sacred Wolf -1040 : Beacon Behemoth -1040 : Hell's Thunder -1039 : Bloodhall Ooze -1039 : Winged Coatl -1038 : Regress -1038 : Tuktuk Scrapper -1038 : Ruthless Cullblade -1038 : Captivating Vampire -1038 : Mind Spring -1038 : Emerald Oryx -1038 : Steward of Valeron -1037 : Devastating Summons -1037 : Calcite Snapper -1037 : Blightning -1037 : Cloudheath Drake -1036 : Recurring Insight -1036 : Hellspark Elemental -1036 : Rhox Brute -1035 : Saberclaw Golem -1034 : Reality Spasm -1034 : Drowned Catacomb -1034 : Dragonskull Summit -1034 : Sigil of the Empty Throne -1033 : Tower of Calamities -1033 : Bojuka Brigand -1033 : Time Reversal -1032 : Bramblesnap -1032 : Groundswell -1032 : Treasure Hunt -1032 : Kathari Screecher -1031 : Vampire Lacerator -1031 : Daggerback Basilisk -1030 : Prey's Vengeance -1030 : Augury Owl -1030 : Fling -1029 : Blackcleave Goblin -1029 : Wall of Frost -1029 : Brave the Elements -1027 : Pyromancer Ascension -1027 : Grixis Slavedriver -1026 : Soulsurge Elemental -1026 : Putrefy -1025 : Makindi Shieldmate -1025 : Abuna Acolyte -1024 : Alpha Tyrannax -1023 : Quest for the Gemblades -1023 : Wind Zendikon -1023 : Mist Leopard -1023 : Esper Cormorants -1022 : Expedition Map -1022 : Dread Drone -1022 : Everflowing Chalice -1022 : Prized Unicorn -1022 : Griffin Sentinel -1022 : Skyknight Legionnaire -1022 : Ardent Plea -1021 : Nightguard Patrol -1020 : Giant Growth -1020 : Dregscape Zombie -1019 : Nacatl Outlander -1019 : Molten-Tail Masticore -1017 : Repel the Darkness -1017 : Gravitational Shift -1017 : Bloodthrone Vampire -1016 : Whiplash Trap -1016 : Bloodshot Trainee -1016 : Guard Duty -1016 : Akoum Battlesinger -1016 : Sejiri Merfolk -1016 : Gravedigger -1015 : Hyena Umbra -1014 : Æther Figment -1013 : Umbra Mystic -1013 : Akoum Boulderfoot -1012 : Crypt of Agadeem -1012 : Mnemonic Wall -1012 : Plummet -1012 : Watchwolf -1011 : Vastwood Gorger -1011 : Moriok Replica -1011 : Sky-Eel School -1011 : Zombie Outlander -1011 : Incurable Ogre -1010 : Emerge Unscathed -1010 : Runeclaw Bear -1010 : Vectis Silencers -1009 : Kor Duelist -1009 : Wall of Denial -1008 : Inexorable Tide -1007 : Chrome Steed -1007 : Survival Cache -1007 : Pilgrim's Eye -1006 : Jaddi Lifestrider -1006 : Vastwood Animist -1006 : Sigil of Distinction -1006 : Yoked Plowbeast -1005 : Sighted-Caste Sorcerer -1004 : Bala Ged Scorpion -1004 : Halimar Excavator -1004 : Sunpetal Grove -1004 : Stone Golem -1003 : Jwar Isle Refuge -1003 : Vectis Agents -1003 : Gold Myr -1002 : Mysteries of the Deep -1002 : Negate -1002 : Pestilent Kathari -1001 : Halimar Depths -1001 : Glass Golem -1000 : Lust for War -1000 : Realms Uncharted -1000 : Affa Guard Hound -1000 : Roc Egg -999 : Ajani's Pridemate -998 : Aether Tradewinds -998 : Weakness -997 : Eel Umbra -997 : Drudge Skeletons -995 : Vulshok Replica -995 : Ferrovore -995 : Molten Frame -995 : Jungle Weaver -994 : Akoum Refuge -994 : Wind Drake -993 : AEther Adept -992 : Cobra Trap -992 : Summit Apes -992 : Cylian Elf -992 : Talon Trooper -991 : Colossal Might -990 : Vulshok Heartstoker -990 : Warmonger's Chariot -990 : Silvercoat Lion -989 : Sunspear Shikari -988 : Slavering Nulls -986 : Spidersilk Net -986 : Unstable Footing -986 : Razorfield Thresher -986 : Gnarlid Pack -986 : Votary of the Conclave -986 : Zephyr Sprite -985 : Grappler Spider -985 : Grayscaled Gharial -984 : Snapsail Glider -984 : Goblin Chieftain -983 : Soul's Majesty -983 : Hellkite Overlord -982 : Diabolic Tutor -982 : Soul Warden -982 : Akrasan Squire -982 : Wildfield Borderpost -981 : Graypelt Refuge -980 : Sejiri Refuge -980 : Instill Infection -980 : Spider Umbra -980 : Celestial Purge -980 : Bone Saw -980 : Dispeller's Capsule -979 : Teetering Peaks -979 : Soliton -979 : Scepter of Insight -978 : Kazandu Refuge -978 : Valakut Fireboar -978 : Warpath Ghoul -977 : Filigree Angel -977 : Fume Spitter -976 : Inquisition of Kozilek -975 : Traumatize -975 : Tukatongue Thallid -975 : Aerie Mystics -974 : Savage Silhouette -974 : Kiln Fiend -973 : Rhox Bodyguard -972 : Vulshok Berserker -972 : Obelisk of Jund -971 : Marsh Threader -970 : Vampire's Bite -970 : Narrow Escape -970 : Wrap in Flames -970 : Diminish -970 : Cavern Thoctar -970 : Filigree Sages -969 : Stomper Cub -969 : Bazaar Trader -969 : Manic Vandal -969 : Scepter of Dominance -968 : Lavafume Invoker -968 : Font of Mythos -968 : Outrider of Jhess -968 : Undead Leotau -967 : Moriok Reaver -967 : Sporecap Spider -967 : Spell Contortion -967 : Arc Runner -967 : Firewild Borderpost -967 : Jhessian Lookout -966 : Brindle Boar -965 : Serra Ascendant -965 : Veinfire Borderpost -964 : Magosi, the Waterveil -964 : Deprive -964 : Lava Axe -962 : Thrummingbird -962 : Ezuri's Archers -962 : Copper Myr -962 : Lone Missionary -962 : Quest for Renewal -962 : Permafrost Trap -962 : Dimir Signet -962 : Etherium Abomination -962 : Glory of Warfare -961 : Hagra Crocodile -961 : Iron Myr -961 : Ikiral Outrider -961 : Null Champion -961 : Dreg Reaver -961 : Valeron Outlander -960 : Might of the Masses -960 : Golgari Signet -959 : Carrion Call -959 : Salvage Scout -958 : Ior Ruin Expedition -958 : Horned Turtle -957 : Molder Beast -957 : Halimar Wavewatch -956 : Molten Ravager -956 : Origin Spellbomb -956 : Goblin Roughrider -956 : Shiv's Embrace -955 : Alpha Tyrranax -954 : Vent Sentinel -954 : Gloomhunter -954 : Rampant Growth -953 : Kor Outfitter -953 : Needlebite Trap -953 : Wing Puncture -953 : Amulet of Vigor -952 : Obelisk of Naya -951 : Lifesmith -951 : Kranioceros -950 : Grim Discovery -950 : Kelinore Bat -950 : Quenchable Fire -949 : Slaughter Cry -949 : Merfolk Sovereign -948 : Seascape Aerialist -948 : Bant Battlemage -948 : Mistvein Borderpost -946 : Wall of Tanglecord -946 : Brood Birthing -946 : Guardians of Akrasa -945 : Joraga Bard -945 : Hedron Rover -944 : Goblin War Paint -944 : Exsanguinate -943 : Slingbow Trap -942 : Gloryscale Viashino -942 : Goblin Mountaineer -941 : Escaped Null -941 : Inspired Charge -941 : Terramorphic Expanse -941 : Temple Bell -941 : Excommunicate -941 : Onyx Goblet -940 : Culling Dais -940 : Elite Vanguard -939 : Kraken Hatchling -938 : Marble Chalice -937 : Quag Vampires -936 : Trailblazer's Boots -936 : Necrotic Plague -934 : Leyline of Vitality -933 : Wall of Bone -933 : Disorient -932 : Merfolk Wayfinder -932 : Withstand Death -931 : Distortion Strike -931 : Claws of Valakut -931 : Deathmark -930 : Soulbound Guardians -930 : Valiant Guard -930 : Spellbreaker Behemoth -930 : Vedalken Outlander -929 : Prophetic Prism -928 : Soul Stair Expedition -928 : Quest for Ula's Temple -926 : Cancel -926 : Ruinous Minotaur -926 : Psychic Miasma -924 : Skitter of Lizards -923 : Soul Parry -923 : Quest for the Nihil Stone -922 : Sylvok Lifestaff -922 : Pennon Blade -921 : Tempest Owl -921 : Combust -920 : Archmage Ascension -920 : Hedron Scrabbler -920 : Lagac Lizard -920 : Enclave Elite -920 : Obelisk of Grixis -919 : Selesnya Signet -918 : Scythe Tiger -918 : Flight Spellbomb -918 : Ruin Ghost -917 : Lay Bare -917 : Bog Wraith -917 : Acolyte of Xathrid -916 : Wall of Faith -914 : Surrakar Banisher -914 : Dread Statuary -914 : Obelisk of Esper -913 : Screeching Silcaw -913 : Furnace Celebration -913 : Snapping Creeper -912 : Battle Hurda -911 : Nether Horror -911 : Howling Mine -910 : Obelisk of Bant -910 : Knotvine Mystic -909 : Seismic Shudder -908 : Copperline Gorge -908 : Suffer the Past -907 : Corrupted Zendikon -907 : Oakenform -907 : Fieldmist Borderpost -906 : Dreamstone Hedron -905 : Fusion Elemental -904 : Terra Eternal -904 : Infantry Veteran -904 : Boros Signet -903 : Dreadwing -902 : Twitch -901 : Surreal Memoir -900 : Dross Hopper -900 : Quicksand -900 : Khalni Garden -899 : Earth Servant -899 : Constricting Tendrils -898 : Quest for Pure Flame -898 : Kabira Crossroads -898 : Leonin Arbiter -898 : Blackcleave Cliffs -897 : Ricochet Trap -897 : Gargoyle Sentinel -896 : Vastwood Zendikon -894 : Spreading Seas -894 : Seize the Initiative -894 : Seachrome Coast -894 : Baneful Omen -893 : Explosive Revelation -892 : Razorverge Thicket -891 : Roofstalker Wight -889 : Redirect -888 : Selective Memory -887 : Silver Myr -886 : Grotag Thrasher -886 : Sejiri Steppe -886 : Unsummon -884 : Shoal Serpent -884 : Darkslick Shores -884 : Semblance Anvil -882 : Goblin Arsonist -881 : Mind Rot -881 : Rotting Legion -880 : Crusher Zendikon -880 : Angel's Mercy -879 : Spell Pierce -879 : Corrupted Harvester -879 : Leaden Myr -878 : Alluring Siren -877 : Quest for the Holy Relic -877 : Cast Through Time -877 : Angelsong -876 : Shieldmate's Blessing -876 : Bold Defense -876 : Noble Vestige -876 : Tanglesap -876 : Scrib Nibblers -875 : Soaring Seacliff -875 : Landbind Ritual -874 : Nimbus Wings -874 : Pulse Tracker -874 : Canyon Minotaur -873 : Eland Umbra -872 : Zendikar Farguide -872 : Tunnel Ignus -872 : Goblin Piker -871 : Mighty Leap -870 : Luminous Wake -870 : Ogre Sentry -870 : Glory Seeker -868 : Quest for Ancient Secrets -868 : Turntimber Grove -868 : Brink of Disaster -868 : Kitesail Apprentice -867 : Auriok Replica -866 : Guardian Zendikon -865 : Relic Crush -865 : Fiery Hellhound -864 : Lethargy Trap -864 : Zof Shade -863 : Mire Blight -863 : Vector Asp -863 : Naturalize -863 : Silence -863 : Flashfreeze -860 : Dormant Gomazoa -860 : Leaf Arrow -859 : Call to Mind -859 : Inkwell Leviathan -858 : Caller of Gales -858 : Trapmaker's Snare -858 : Carnage Altar -858 : Memnite -858 : Nature's Claim -856 : Scoria Elemental -856 : Mass Polymorph -856 : Coral Merfolk -855 : Dark Tutelage -854 : Dissipation Field -853 : Kuldotha Rebirth -852 : Pillarfield Ox -851 : Irresistible Prey -848 : Shrivel -847 : Runeflare Trap -847 : Mindless Null -847 : Disentomb -846 : Veteran's Reflexes -845 : Cosi's Ravager -844 : Smoldering Spires -844 : Relentless Rats -842 : Piranha Marsh -842 : Oxidda Daredevil -842 : Thunder Strike -840 : Evolving Wilds -840 : Goblin Tunneler -840 : Viscera Seer -840 : Solemn Offering -838 : Rest for the Weary -838 : Palace Guard -836 : Nema Siltlurker -836 : Skittering Invasion -835 : Bog Tatters -835 : Siege Mastodon -833 : Plated Seastrider -833 : Volcanic Strength -833 : Kraken's Eye -832 : Copperhorn Scout -831 : Safe Passage -830 : Harmless Assault -830 : Armored Cancrix -829 : Bull Rush -828 : Harbor Serpent -828 : Merfolk Spy -827 : Leyline of Anticipation -827 : Unholy Strength -825 : Assault Strobe -821 : Holy Strength -821 : Jinxed Idol -819 : Beast Hunt -817 : Merfolk Observer -817 : Leyline of the Void -816 : Bog Raiders -816 : Goblin Balloon Brigade -816 : Phantom Beast -815 : Duress -814 : Repay In Kind -814 : Primal Cocoon -813 : Clone Shell -812 : Twisted Image -812 : Painful Quandary -812 : Haze Frog -810 : Panic Spellbomb -810 : Blunt the Assault -810 : Mire's Toll -808 : Necrogen Censer -808 : Curse of Wizardry -807 : Ravenous Trap -807 : Shared Discovery -806 : Desecrated Earth -806 : Accorder's Shield -806 : Venser's Journal -806 : Leyline of Punishment -805 : Turn Aside -805 : Fleeting Distraction -804 : Demolish -803 : Raid Bombardment -803 : Maritime Guard -803 : Wall of Vines -801 : Roiling Terrain -800 : Jace's Erasure -797 : Phantasmal Abomination -797 : Bojuka Bog -796 : Perish the Thought -796 : Demystify -793 : Sunspring Expedition -792 : Blistergrub -792 : Death Cultist -792 : Crab Umbra -790 : Caravan Hurda -790 : Ancient Stirrings -790 : Gravity Well -790 : Nature's Spiral -786 : Goblin Gaveleer -786 : Molten Psyche -786 : Dispel -785 : Ajani's Mantra -783 : Memoricide -782 : Razor Boomerang -782 : Feral Contest -780 : Hornet Sting -778 : Shape Anew -778 : Walking Atlas -777 : Jwari Scuttler -777 : Dragon's Claw -776 : Demon's Horn -775 : Leyline of Sanctity -775 : Tireless Missionaries -774 : Fulgent Distraction -774 : Loxodon Wayfarer -773 : Unified Will -764 : Trapfinder's Trick -763 : Trigon of Mending -758 : Quest for the Goblin Lord -756 : Pyretic Ritual -755 : Relic Putrescence -754 : Liquimetal Coating -750 : Darksteel Myr -750 : Nihil Spellbomb -750 : Goldenglow Moth -747 : Rumbling Aftershocks -745 : Fog -743 : Tome Scour -741 : Bloodcrazed Goblin -739 : Golem Foundry -739 : Viridian Revel -739 : Elixir of Immortality -739 : Wild Evocation -734 : Haunting Echoes -732 : Contaminated Ground -732 : Blood Tithe -726 : Enatu Golem -724 : Aura Finesse -723 : Back to Nature -721 : Demonic Appetite -715 : Vault Skyward -712 : Nighthaze -710 : Autumn's Veil -703 : Melt Terrain -702 : Reinforced Bulwark -696 : Vigil for the Lost -693 : Dryad's Favor -692 : Golden Urn -688 : Fissure Vent -686 : Living Destiny -684 : Ornithopter -679 : Echo Circlet -678 : Runed Servitor -669 : Hunters' Feast -650 : Liliana's Caress -644 : Not Of This World -640 : Golem's Heart -633 : Swamp -633 : Mountain -615 : Whitesun's Passage -612 : Sorcerer's Strongbox -604 : Incite -588 : Forest -586 : Voltaic Key -577 : Plains -574 : Island -572 : Tectonic Edge -554 : Angel's Feather -535 : Wurm's Tooth diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/aer.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/aer.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/akh.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/akh.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/akh.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/akh.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/dom.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/dom.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/dom.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/dom.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/grn.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/grn.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/grn.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/grn.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/hou.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/hou.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/hou.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/hou.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ima.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/ima.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ima.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/ima.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/kld.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/kld.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/m13.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/m13.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/m13.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/m13.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/m19.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/m19.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/m19.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/m19.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/mm3.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/mm3.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/mm3.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/mm3.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/rix.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/rix.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/rix.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/rix.csv diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/setsWithRatings.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/setsWithRatings.csv similarity index 98% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/setsWithRatings.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/setsWithRatings.csv index 172ed6537e..bede958f23 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/setsWithRatings.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/setsWithRatings.csv @@ -16,4 +16,5 @@ aer kld mm3 ima -m13 \ No newline at end of file +m13 +ktk \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/xln.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/xln.csv similarity index 100% rename from Mage.Server.Plugins/Mage.Player.AI/src/main/resources/xln.csv rename to Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/xln.csv From a95f3b2211ed8ad060b530d5a6194ae336c7772f Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 28 Oct 2018 14:27:06 -0700 Subject: [PATCH 091/167] remove ktk from list of sets with ratings haven't commited the ktk rating numbers, need to remove it from the list --- .../src/main/resources/ratings/setsWithRatings.csv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/setsWithRatings.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/setsWithRatings.csv index bede958f23..172ed6537e 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/setsWithRatings.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/setsWithRatings.csv @@ -16,5 +16,4 @@ aer kld mm3 ima -m13 -ktk \ No newline at end of file +m13 \ No newline at end of file From 08d895d110bd3838bfe8b1ed5d2452d4060213b8 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 28 Oct 2018 15:20:51 -0700 Subject: [PATCH 092/167] fix typos in card ratings files --- .../Mage.Player.AI/src/main/resources/ratings/aer.csv | 2 +- .../Mage.Player.AI/src/main/resources/ratings/akh.csv | 2 +- .../Mage.Player.AI/src/main/resources/ratings/kld.csv | 2 +- .../Mage.Player.AI/src/main/resources/ratings/mm3.csv | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv index d586ce8d8c..d5bc30212e 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv @@ -181,4 +181,4 @@ Wrangle:543 Ornithopter:177 Gonti’s Machinations:167 Prizefighter Construct:123 -184 Secret Salvage 77 \ No newline at end of file +Secret Salvage 77 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/akh.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/akh.csv index aa35d0b68e..168d2671cc 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/akh.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/akh.csv @@ -246,4 +246,4 @@ Ancient Crab:198 Sunscorched Desert:186 Dispossess:109 Protection of the Hekma:108 -249 Gate to the Afterlife 95 \ No newline at end of file +Gate to the Afterlife 95 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv index d586ce8d8c..8801646b1a 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv @@ -181,4 +181,4 @@ Wrangle:543 Ornithopter:177 Gonti’s Machinations:167 Prizefighter Construct:123 -184 Secret Salvage 77 \ No newline at end of file +Secret Salvage:77 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/mm3.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/mm3.csv index d088c3d513..3d175cd059 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/mm3.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/mm3.csv @@ -235,7 +235,7 @@ Auramancer:1346 Haunted Fengraf:1343 Strionic Resonator:1342 Act of Heroism:1341 -Borrowing:100,000 Arrows 1338 +Borrowing 100,000 Arrows:1338 Jackal Pup:1337 Valor in Akros:1337 Nihil Spellbomb:1316 From 43f32f9640bb8d6b9ed8c2549c92752197262206 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 28 Oct 2018 15:24:06 -0700 Subject: [PATCH 093/167] card ratings files fixes/updates fixed kld and aer --- .../src/main/resources/ratings/aer.csv | 2 +- .../src/main/resources/ratings/kld.csv | 458 +++++++++++------- 2 files changed, 275 insertions(+), 185 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv index d5bc30212e..8801646b1a 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/aer.csv @@ -181,4 +181,4 @@ Wrangle:543 Ornithopter:177 Gonti’s Machinations:167 Prizefighter Construct:123 -Secret Salvage 77 \ No newline at end of file +Secret Salvage:77 \ No newline at end of file diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv index 8801646b1a..21f062e5c1 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv @@ -1,184 +1,274 @@ -Ajani Unyielding:40114 -Herald of Anguish:39905 -Rishkar, Peema Renegade:39137 -Aethersphere Harvester:38827 -Heart of Kiran:37403 -Yahenni’s Expertise:37199 -Tezzeret the Schemer:34694 -Solemn Recruit:34338 -Untethered Express:33419 -Battle at the Bridge:33072 -Yahenni, Undying Partisan:32377 -Fatal Push:32126 -Sram’s Expertise:32076 -Walking Ballista:31052 -Baral’s Expertise:30879 -Freejam Regent:30870 -Glint-Sleeve Siphoner:30022 -Ridgescale Tusker:30018 -Quicksmith Spy:29214 -Scrapper Champion:29176 -Aethertide Whale:28976 -Daring Demolition:28538 -Gifted Aetherborn:28163 -Quicksmith Rebel:27792 -Hungry Flames:27737 -Thopter Arrest:27574 -Exquisite Archangel:27415 -Kari Zev, Skyship Raider:27188 -Aetherwind Basker:26371 -Treasure Keeper:26283 -Greenbelt Rampager:26185 -Vengeful Rebel:25902 -Aethergeode Miner:25711 -Rishkar’s Expertise:25327 -Lightning Runner:25297 -Shock:25129 -Caught in the Brights:24815 -Lifecrafter’s Bestiary:24466 -Midnight Entourage:23732 -Sram, Senior Edificer:23386 -Metallic Mimic:23383 -Maulfist Revolutionary:23093 -Greenwheel Liberator:21817 -Chandra’s Revolution:21713 -Maverick Thopterist:21685 -Airdrop Aeronauts:21061 -Narnam Renegade:20406 -Winding Constrictor:20174 -Scrap Trawler:20001 -Monstrous Onslaught:19528 -Wind-Kin Raiders:19507 -Deadeye Harpooner:19305 -Skyship Plunderer:18967 -Aether Poisoner:18617 -Cruel Finality:18352 -Release the Gremlins:18286 -Aether Chaser:17813 -Rogue Refiner:17646 -Reckless Racer:17299 -Dawnfeather Eagle:17238 -Felidar Guardian:17122 -Prey Upon:16986 -Spire Patrol:16942 -Druid of the Cowl:16941 -Aetherstream Leopard:16826 -Reverse Engineer:15858 -Daredevil Dragster:15795 -Shielded Aether Thief:15596 -Scrounging Bandar:14827 -Lifecraft Cavalry:14821 -Pacification Array:14672 -Renegade Rallier:14442 -Trophy Mage:14084 -Enraged Giant:13989 -Foundry Hornet:13907 -Call for Unity:13832 -Renegade Wheelsmith:13717 -Peacewalker Colossus:13604 -Sweatworks Brawler:13229 -Aether Swooper:13171 -Outland Boar:13074 -Restoration Specialist:12713 -Perilous Predicament:12702 -Aeronaut Admiral:12409 -Tezzeret’s Touch:12281 -Oath of Ajani:11663 -Bastion Inventor:11485 -Weldfast Engineer:11309 -Countless Gears Renegade:11144 -Mechanized Production:10887 -Hinterland Drake:10667 -Consulate Crackdown:10549 -Renegade Map:10115 -Peema Aether-Seer:9906 -Unbridled Growth:9661 -Lifecraft Awakening:9620 -Baral, Chief of Compliance:9382 -Merchant’s Dockhand:9033 -Barricade Breaker:8635 -Lifecrafter’s Gift:8248 -Hidden Herbalists:8012 -Mobile Garrison:7976 -Aether Herder:7964 -Disallow:7550 -Kari Zev’s Expertise:7472 -Cogwork Assembler:7463 -Heroic Intervention:6922 -Hidden Stockpile:6732 -Illusionist’s Stratagem:6678 -Leave in the Dust:6675 -Ghirapur Osprey:6597 -Decommission:6354 -Ice Over:6297 -Night Market Aeronaut:6198 -Gremlin Infestation:6195 -Spire of Industry:6181 -Audacious Infiltrator:6084 -Sly Requisitioner:5718 -Alley Strangler:5595 -Silkweaver Elite:5574 -Aid from the Cowl:5463 -Highspire Infusion:5402 -Frontline Rebel:5350 -Invigorated Rampage:5268 -Defiant Salvager:5211 -Watchful Automaton:5147 -Siege Modification:5142 -Inspiring Statuary:4932 -Embraal Gear-Smasher:4847 -Deft Dismissal:4727 -Shipwreck Moray:4645 -Metallic Rebuke:4618 -Dispersal Technician:4389 -Resourceful Return:4325 -Efficient Construction:4108 -Welder Automaton:4076 -Aether Inspector:3989 -Ravenous Intruder:3963 -Ironclad Revolutionary:3930 -Implement of Ferocity:3720 -Alley Evasion:3712 -Hope of Ghirapur:3699 -Aerial Modification:3671 -Gonti’s Aether Heart:3295 -Foundry Assembler:3292 -Fen Hauler:3265 -Natural Obsolescence:3262 -Destructive Tampering:3239 -Implement of Examination:3217 -Irontread Crusher:3097 -Filigree Crawler:3020 -Servo Schematic:3006 -Verdant Automaton:2979 -Reservoir Walker:2918 -Whir of Invention:2916 -Paradox Engine:2714 -Salvage Scuttler:2677 -Augmenting Automaton:2636 -Fourth Bridge Prowler:2448 -Conviction:2411 -Lathnu Sailback:2352 -Planar Bridge:2348 -Night Market Guard:2244 -Bastion Enforcer:2236 -Precise Strike:2179 -Universal Solvent:2128 -Implement of Malice:2089 -Crackdown Construct:1926 -Dark Intimations:1876 -Pia’s Revolution:1850 -Renegade’s Getaway:1472 -Aegis Automaton:1355 -Consulate Dreadnought:1255 -Indomitable Creativity:1206 -Negate:1016 -Consulate Turret:1014 -Implement of Combustion:806 -Take into Custody:678 -Implement of Improvement:624 -Wrangle:543 -Ornithopter:177 -Gonti’s Machinations:167 -Prizefighter Construct:123 -Secret Salvage:77 \ No newline at end of file +Sword of Feast and Famine : 6746 +Chandra, Torch of Defiance :6461 +Skysovereign, Consul Flagship :6340 +Noxious Gearhulk :6262 +Sword of Fire and Ice :6222 +Angel of Invention :6000 +Verdurous Gearhulk :5971 +Demon of Dark Schemes :5893 +Sol Ring :5688 +Cataclysmic Gearhulk :5638 +Torrential Gearhulk :5628 +Nissa, Vital Force :5565 +Hangarback Walker :5500 +Gonti, Lord of Luxury :5474 +Steel Overseer :5392 +Skyship Stalker :5383 +Pia Nalaar :5351 +Sword of Light and Shadow :5346 +Smuggler's Copter :5342 +Confiscation Coup :5338 +Combustible Gearhulk :5326 +Oviya Pashiri, Sage Lifecrafte :5317 +Mana Crypt :5268 +Solemn Simulacrum :5257 +Mana Vault :5228 +Harnessed Lightning :5209 +Aetherstorm Roc :5194 +Cultivator's Caravan :5103 +Fairgrounds Warden :5100 +Rashmi, Eternities Crafter :5054 +Dovin Baan :5038 +Aerial Responder :5017 +Saheeli's Artistry :5014 +Bristling Hydra :4996 +Master Trinketeer :4979 +Welding Sparks :4971 +Cultivator of Blades :4895 +Aethersquall Ancient :4780 +Longtusk Cub :4744 +Unlicensed Disintegration :4673 +Snare Thopter :4657 +Fleetwheel Cruiser :4639 +Depala, Pilot Exemplar :4628 +Multiform Wonder :4625 +Cloudblazer :4603 +Filigree Familiar :4589 +Gauntlet of Power :4586 +Skywhaler's Shot :4582 +Renegade Freighter :4580 +Fumigate :4541 +Chromatic Lantern :4425 +Champion's Helm :4328 +Revoke Privileges :4313 +Peema Outrider :4305 +Arborback Stomper :4263 +Architect of the Untamed :4245 +Tidy Conclusion :4243 +Servant of the Conduit :4224 +Aetherborn Marauder :4185 +Essence Extraction :4136 +Saheeli Rai :4130 +Chief of the Foundry :4124 +Syndicate Trafficker :4030 +Lathnu Hellion :4026 +Bomat Bazaar Barge :4021 +Visionary Augmenter :3975 +Foundry Inspector :3930 +Wispweaver Angel :3924 +Gearshift Ace :3921 +Mox Opal :3921 +Key to the City :3912 +Furious Reprisal :3892 +Captured by the Consulate :3890 +Scrapheap Scrounger :3837 +Aethertorch Renegade :3817 +Die Young :3810 +Whirler Virtuoso :3801 +Animation Module :3776 +Æther Vial :3765 +Marionette Master :3742 +Nature's Way :3737 +Chandra's Pyrohelix :3714 +Long-Finned Skywhale :3713 +Aether Meltdown :3699 +Restoration Gearsmith :3653 +Empyreal Voyager :3650 +Ovalchase Daredevil :3634 +Thriving Rhino :3584 +Hunt the Weak :3579 +Veteran Motorist :3553 +Voltaic Brawler :3544 +Lightning Greaves :3531 +Dynavolt Tower :3505 +Scroll Rack :3483 +Padeem, Consul of Innovation :3470 +Shrewd Negotiation :3470 +Propeller Pioneer :3422 +Kambal, Consul of Allocation :3405 +Malfunction :3399 +Brazen Scourge :3395 +Chrome Mox :3369 +Ballista Charger :3358 +Sculpting Steel :3327 +Glint-Sleeve Artisan :3308 +Gearseeker Serpent :3290 +Glint-Nest Crane :3289 +Armorcraft Judge :3279 +Thriving Grubs :3265 +Sky Skiff :3264 +Speedway Fanatic :3261 +Riparian Tiger :3250 +Underhanded Designs :3235 +Kujar Seedsculptor :3231 +Maulfist Doorbuster :3227 +Subtle Strike :3186 +Mind's Eye :3172 +Impeccable Timing :3164 +Spontaneous Artist :3155 +Foundry Screecher :3125 +Elegant Edgecrafters :3112 +Weaponcraft Enthusiast :3093 +Contraband Kingpin :3085 +Consul's Shieldguard :3077 +Glimmer of Genius :3068 +Eliminate the Competition :3032 +Metalwork Colossus :3028 +Aetherworks Marvel :3020 +Aviary Mechanic :3008 +Aether Hub :2995 +Fateful Showdown :2968 +Prophetic Prism :2950 +Experimental Aviator :2940 +Metallurgic Summonings :2937 +Aether Theorist :2936 +Rings of Brighthearth :2869 +Toolcraft Exemplar :2860 +Attune with Aether :2849 +Thriving Ibex :2845 +Narnam Cobra :2841 +Quicksmith Genius :2826 +Fabrication Module :2806 +Lotus Petal :2788 +Thriving Rats :2782 +Insidious Will :2777 +Embraal Bruiser :2772 +Maulfist Squad :2766 +Dhund Operative :2751 +Cloudstone Curio :2739 +Salivating Gremlins :2709 +Janjeet Sentry :2690 +Static Orb :2655 +Era of Innovation :2652 +Fairgrounds Trumpeter :2651 +Wind Drake :2651 +Lawless Broker :2634 +Ovalchase Dragster :2629 +Fragmentize :2614 +Blossoming Defense :2592 +Built to Last :2582 +Territorial Gorger :2581 +Skyswirl Harrier :2566 +Rush of Vitality :2565 +Wild Wanderer :2549 +Deadlock Trap :2538 +Spireside Infiltrator :2522 +Durable Handicraft :2512 +Prakhata Pillar-Bug :2508 +Dukhara Peafowl :2503 +Sage of Shaila's Claim :2492 +Incendiary Sabotage :2474 +Weldfast Monitor :2463 +Trusty Companion :2452 +Iron League Steed :2450 +Spark of Creativity :2440 +Self-Assembler :2433 +Make Obsolete :2431 +Select for Inspection :2431 +Live Fast :2420 +Ambitious Aetherborn :2404 +Thriving Turtle :2397 +Nimble Innovator :2390 +Eager Construct :2382 +Servo Exhibition :2377 +Appetite for the Unnatural :2372 +Midnight Oil :2357 +Eddytrail Hawk :2352 +Æther Tradewinds :2337 +Reckless Fireweaver :2334 +Weldfast Wingsmith :2332 +Ghirapur Guide :2331 +Electrostatic Pummeler :2322 +Painter's Servant :2300 +Bastion Mastodon :2293 +Highspire Artisan :2258 +Cathartic Reunion :2239 +Wayward Giant :2226 +Acrobatic Maneuver :2225 +Crucible of Worlds :2221 +Built to Smash :2214 +Prakhata Club Security :2214 +Vedalken Blademaster :2205 +Panharmonicon :2186 +Decoction Module :2185 +Inventor's Apprentice :2178 +Fretwork Colony :2120 +Hightide Hermit :2102 +Spirebluff Canal :2095 +Botanical Sanctum :2072 +Blooming Marsh :2018 +Whirlermaker :1951 +Concealed Courtyard :1946 +Wildest Dreams :1930 +Tezzeret's Ambition :1922 +Ninth Bridge Patrol :1884 +Metalspinner's Puzzleknot :1872 +Inspiring Vantage :1868 +Ruinous Gremlin :1845 +Inventors' Fair :1830 +Herald of the Fair :1812 +Hazardous Conditions :1749 +Glassblower's Puzzleknot :1703 +Hijack :1693 +Engineered Might :1676 +Bomat Courier :1673 +Night Market Lookout :1670 +Inventor's Goggles :1664 +Cowl Prowler :1640 +Dukhara Scavenger :1638 +Ornamental Courage :1593 +Fortuitous Find :1586 +Demolition Stomper :1578 +Cogworker's Puzzleknot :1563 +Creeping Mold :1526 +Aradara Express :1518 +Minister of Inquiries :1499 +Harsh Scrutiny :1487 +Accomplished Automaton :1480 +Woodweaver's Puzzleknot :1459 +Failed Inspection :1458 +Diabolic Tutor :1454 +Consulate Skygate :1452 +Refurbish :1452 +Disappearing Act :1425 +Pressure Point :1424 +Authority of the Consuls :1398 +Workshop Assistant :1383 +Inspired Charge :1365 +Take Down :1343 +Renegade Tactics :1330 +Larger Than Life :1326 +Revolutionary Rebuff :1320 +Ceremonious Rejection :1318 +Torch Gauntlet :1295 +Fireforger's Puzzleknot :1285 +Morbid Curiosity :1273 +Ghirapur Orrery :1261 +Paradoxical Outcome :1257 +Curio Vendor :1234 +Aetherflux Reservoir :1222 +Start Your Engines :1221 +Terror of the Fairgrounds :1200 +Demolish :1197 +Wily Bandar :1181 +Consulate Surveillance :1167 +Giant Spectacle :1101 +Mind Rot :1101 +Lost Legacy :1092 +Commencement of Festivities :1064 +Sequestered Stash :1062 +Madcap Experiment :1061 +Tasseled Dromedary :1028 +Dramatic Reversal :1001 +Perpetual Timepiece :993 +Dubious Challenge :976 \ No newline at end of file From 83afff5a05f432ae91d0ad263c88b4fe83a1c565 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 28 Oct 2018 16:18:53 -0700 Subject: [PATCH 094/167] kld card ratings draftaholics data was very skewed towards masterpieces. which meant decent cards were ranking very low relatively I used the relative ranking from draftaholics and generated a normal distribution mean60 std 20 for these rankings to smooth it out. --- .../src/main/resources/ratings/kld.csv | 548 +++++++++--------- 1 file changed, 274 insertions(+), 274 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv index 21f062e5c1..b477e4f360 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/kld.csv @@ -1,274 +1,274 @@ -Sword of Feast and Famine : 6746 -Chandra, Torch of Defiance :6461 -Skysovereign, Consul Flagship :6340 -Noxious Gearhulk :6262 -Sword of Fire and Ice :6222 -Angel of Invention :6000 -Verdurous Gearhulk :5971 -Demon of Dark Schemes :5893 -Sol Ring :5688 -Cataclysmic Gearhulk :5638 -Torrential Gearhulk :5628 -Nissa, Vital Force :5565 -Hangarback Walker :5500 -Gonti, Lord of Luxury :5474 -Steel Overseer :5392 -Skyship Stalker :5383 -Pia Nalaar :5351 -Sword of Light and Shadow :5346 -Smuggler's Copter :5342 -Confiscation Coup :5338 -Combustible Gearhulk :5326 -Oviya Pashiri, Sage Lifecrafte :5317 -Mana Crypt :5268 -Solemn Simulacrum :5257 -Mana Vault :5228 -Harnessed Lightning :5209 -Aetherstorm Roc :5194 -Cultivator's Caravan :5103 -Fairgrounds Warden :5100 -Rashmi, Eternities Crafter :5054 -Dovin Baan :5038 -Aerial Responder :5017 -Saheeli's Artistry :5014 -Bristling Hydra :4996 -Master Trinketeer :4979 -Welding Sparks :4971 -Cultivator of Blades :4895 -Aethersquall Ancient :4780 -Longtusk Cub :4744 -Unlicensed Disintegration :4673 -Snare Thopter :4657 -Fleetwheel Cruiser :4639 -Depala, Pilot Exemplar :4628 -Multiform Wonder :4625 -Cloudblazer :4603 -Filigree Familiar :4589 -Gauntlet of Power :4586 -Skywhaler's Shot :4582 -Renegade Freighter :4580 -Fumigate :4541 -Chromatic Lantern :4425 -Champion's Helm :4328 -Revoke Privileges :4313 -Peema Outrider :4305 -Arborback Stomper :4263 -Architect of the Untamed :4245 -Tidy Conclusion :4243 -Servant of the Conduit :4224 -Aetherborn Marauder :4185 -Essence Extraction :4136 -Saheeli Rai :4130 -Chief of the Foundry :4124 -Syndicate Trafficker :4030 -Lathnu Hellion :4026 -Bomat Bazaar Barge :4021 -Visionary Augmenter :3975 -Foundry Inspector :3930 -Wispweaver Angel :3924 -Gearshift Ace :3921 -Mox Opal :3921 -Key to the City :3912 -Furious Reprisal :3892 -Captured by the Consulate :3890 -Scrapheap Scrounger :3837 -Aethertorch Renegade :3817 -Die Young :3810 -Whirler Virtuoso :3801 -Animation Module :3776 -Æther Vial :3765 -Marionette Master :3742 -Nature's Way :3737 -Chandra's Pyrohelix :3714 -Long-Finned Skywhale :3713 -Aether Meltdown :3699 -Restoration Gearsmith :3653 -Empyreal Voyager :3650 -Ovalchase Daredevil :3634 -Thriving Rhino :3584 -Hunt the Weak :3579 -Veteran Motorist :3553 -Voltaic Brawler :3544 -Lightning Greaves :3531 -Dynavolt Tower :3505 -Scroll Rack :3483 -Padeem, Consul of Innovation :3470 -Shrewd Negotiation :3470 -Propeller Pioneer :3422 -Kambal, Consul of Allocation :3405 -Malfunction :3399 -Brazen Scourge :3395 -Chrome Mox :3369 -Ballista Charger :3358 -Sculpting Steel :3327 -Glint-Sleeve Artisan :3308 -Gearseeker Serpent :3290 -Glint-Nest Crane :3289 -Armorcraft Judge :3279 -Thriving Grubs :3265 -Sky Skiff :3264 -Speedway Fanatic :3261 -Riparian Tiger :3250 -Underhanded Designs :3235 -Kujar Seedsculptor :3231 -Maulfist Doorbuster :3227 -Subtle Strike :3186 -Mind's Eye :3172 -Impeccable Timing :3164 -Spontaneous Artist :3155 -Foundry Screecher :3125 -Elegant Edgecrafters :3112 -Weaponcraft Enthusiast :3093 -Contraband Kingpin :3085 -Consul's Shieldguard :3077 -Glimmer of Genius :3068 -Eliminate the Competition :3032 -Metalwork Colossus :3028 -Aetherworks Marvel :3020 -Aviary Mechanic :3008 -Aether Hub :2995 -Fateful Showdown :2968 -Prophetic Prism :2950 -Experimental Aviator :2940 -Metallurgic Summonings :2937 -Aether Theorist :2936 -Rings of Brighthearth :2869 -Toolcraft Exemplar :2860 -Attune with Aether :2849 -Thriving Ibex :2845 -Narnam Cobra :2841 -Quicksmith Genius :2826 -Fabrication Module :2806 -Lotus Petal :2788 -Thriving Rats :2782 -Insidious Will :2777 -Embraal Bruiser :2772 -Maulfist Squad :2766 -Dhund Operative :2751 -Cloudstone Curio :2739 -Salivating Gremlins :2709 -Janjeet Sentry :2690 -Static Orb :2655 -Era of Innovation :2652 -Fairgrounds Trumpeter :2651 -Wind Drake :2651 -Lawless Broker :2634 -Ovalchase Dragster :2629 -Fragmentize :2614 -Blossoming Defense :2592 -Built to Last :2582 -Territorial Gorger :2581 -Skyswirl Harrier :2566 -Rush of Vitality :2565 -Wild Wanderer :2549 -Deadlock Trap :2538 -Spireside Infiltrator :2522 -Durable Handicraft :2512 -Prakhata Pillar-Bug :2508 -Dukhara Peafowl :2503 -Sage of Shaila's Claim :2492 -Incendiary Sabotage :2474 -Weldfast Monitor :2463 -Trusty Companion :2452 -Iron League Steed :2450 -Spark of Creativity :2440 -Self-Assembler :2433 -Make Obsolete :2431 -Select for Inspection :2431 -Live Fast :2420 -Ambitious Aetherborn :2404 -Thriving Turtle :2397 -Nimble Innovator :2390 -Eager Construct :2382 -Servo Exhibition :2377 -Appetite for the Unnatural :2372 -Midnight Oil :2357 -Eddytrail Hawk :2352 -Æther Tradewinds :2337 -Reckless Fireweaver :2334 -Weldfast Wingsmith :2332 -Ghirapur Guide :2331 -Electrostatic Pummeler :2322 -Painter's Servant :2300 -Bastion Mastodon :2293 -Highspire Artisan :2258 -Cathartic Reunion :2239 -Wayward Giant :2226 -Acrobatic Maneuver :2225 -Crucible of Worlds :2221 -Built to Smash :2214 -Prakhata Club Security :2214 -Vedalken Blademaster :2205 -Panharmonicon :2186 -Decoction Module :2185 -Inventor's Apprentice :2178 -Fretwork Colony :2120 -Hightide Hermit :2102 -Spirebluff Canal :2095 -Botanical Sanctum :2072 -Blooming Marsh :2018 -Whirlermaker :1951 -Concealed Courtyard :1946 -Wildest Dreams :1930 -Tezzeret's Ambition :1922 -Ninth Bridge Patrol :1884 -Metalspinner's Puzzleknot :1872 -Inspiring Vantage :1868 -Ruinous Gremlin :1845 -Inventors' Fair :1830 -Herald of the Fair :1812 -Hazardous Conditions :1749 -Glassblower's Puzzleknot :1703 -Hijack :1693 -Engineered Might :1676 -Bomat Courier :1673 -Night Market Lookout :1670 -Inventor's Goggles :1664 -Cowl Prowler :1640 -Dukhara Scavenger :1638 -Ornamental Courage :1593 -Fortuitous Find :1586 -Demolition Stomper :1578 -Cogworker's Puzzleknot :1563 -Creeping Mold :1526 -Aradara Express :1518 -Minister of Inquiries :1499 -Harsh Scrutiny :1487 -Accomplished Automaton :1480 -Woodweaver's Puzzleknot :1459 -Failed Inspection :1458 -Diabolic Tutor :1454 -Consulate Skygate :1452 -Refurbish :1452 -Disappearing Act :1425 -Pressure Point :1424 -Authority of the Consuls :1398 -Workshop Assistant :1383 -Inspired Charge :1365 -Take Down :1343 -Renegade Tactics :1330 -Larger Than Life :1326 -Revolutionary Rebuff :1320 -Ceremonious Rejection :1318 -Torch Gauntlet :1295 -Fireforger's Puzzleknot :1285 -Morbid Curiosity :1273 -Ghirapur Orrery :1261 -Paradoxical Outcome :1257 -Curio Vendor :1234 -Aetherflux Reservoir :1222 -Start Your Engines :1221 -Terror of the Fairgrounds :1200 -Demolish :1197 -Wily Bandar :1181 -Consulate Surveillance :1167 -Giant Spectacle :1101 -Mind Rot :1101 -Lost Legacy :1092 -Commencement of Festivities :1064 -Sequestered Stash :1062 -Madcap Experiment :1061 -Tasseled Dromedary :1028 -Dramatic Reversal :1001 -Perpetual Timepiece :993 -Dubious Challenge :976 \ No newline at end of file +Sword of Feast and Famine:100 +Chandra, Torch of Defiance:99 +Skysovereign, Consul Flagship:98 +Noxious Gearhulk:97 +Sword of Fire and Ice:96 +Angel of Invention:95 +Verdurous Gearhulk:94 +Demon of Dark Schemes:94 +Sol Ring:93 +Cataclysmic Gearhulk:92 +Torrential Gearhulk:92 +Nissa, Vital Force:91 +Hangarback Walker:90 +Gonti, Lord of Luxury:90 +Steel Overseer:89 +Skyship Stalker:89 +Pia Nalaar:88 +Sword of Light and Shadow:88 +Smuggler's Copter:87 +Confiscation Coup:87 +Combustible Gearhulk:86 +Oviya Pashiri, Sage Lifecrafte:86 +Mana Crypt:86 +Solemn Simulacrum:85 +Mana Vault:85 +Harnessed Lightning:84 +Aetherstorm Roc:84 +Cultivator's Caravan:84 +Fairgrounds Warden:83 +Rashmi, Eternities Crafter:83 +Dovin Baan:83 +Aerial Responder:82 +Saheeli's Artistry:82 +Bristling Hydra:82 +Master Trinketeer:81 +Welding Sparks:81 +Cultivator of Blades:81 +Aethersquall Ancient:80 +Longtusk Cub:80 +Unlicensed Disintegration:80 +Snare Thopter:79 +Fleetwheel Cruiser:79 +Depala, Pilot Exemplar:79 +Multiform Wonder:79 +Cloudblazer:78 +Filigree Familiar:78 +Gauntlet of Power:78 +Skywhaler's Shot:78 +Renegade Freighter:77 +Fumigate:77 +Chromatic Lantern:77 +Champion's Helm:77 +Revoke Privileges:76 +Peema Outrider:76 +Arborback Stomper:76 +Architect of the Untamed:76 +Tidy Conclusion:75 +Servant of the Conduit:75 +Aetherborn Marauder:75 +Essence Extraction:75 +Saheeli Rai:74 +Chief of the Foundry:74 +Syndicate Trafficker:74 +Lathnu Hellion:74 +Bomat Bazaar Barge:73 +Visionary Augmenter:73 +Foundry Inspector:73 +Wispweaver Angel:73 +Gearshift Ace:73 +Mox Opal:72 +Key to the City:72 +Furious Reprisal:72 +Captured by the Consulate:72 +Scrapheap Scrounger:71 +Aethertorch Renegade:71 +Die Young:71 +Whirler Virtuoso:71 +Animation Module:71 +Æther Vial:70 +Marionette Master:70 +Nature's Way:70 +Chandra's Pyrohelix:70 +Long-Finned Skywhale:70 +Aether Meltdown:69 +Restoration Gearsmith:69 +Empyreal Voyager:69 +Ovalchase Daredevil:69 +Thriving Rhino:69 +Hunt the Weak:68 +Veteran Motorist:68 +Voltaic Brawler:68 +Lightning Greaves:68 +Dynavolt Tower:68 +Scroll Rack:67 +Padeem, Consul of Innovation:67 +Shrewd Negotiation:67 +Propeller Pioneer:67 +Kambal, Consul of Allocation:67 +Malfunction:66 +Brazen Scourge:66 +Chrome Mox:66 +Ballista Charger:66 +Sculpting Steel:66 +Glint-Sleeve Artisan:66 +Gearseeker Serpent:65 +Glint-Nest Crane:65 +Armorcraft Judge:65 +Thriving Grubs:65 +Sky Skiff:65 +Speedway Fanatic:64 +Riparian Tiger:64 +Underhanded Designs:64 +Kujar Seedsculptor:64 +Maulfist Doorbuster:64 +Subtle Strike:64 +Mind's Eye:63 +Impeccable Timing:63 +Spontaneous Artist:63 +Foundry Screecher:63 +Elegant Edgecrafters:63 +Weaponcraft Enthusiast:62 +Contraband Kingpin:62 +Consul's Shieldguard:62 +Glimmer of Genius:62 +Eliminate the Competition:62 +Metalwork Colossus:62 +Aetherworks Marvel:61 +Aviary Mechanic:61 +Aether Hub:61 +Fateful Showdown:61 +Prophetic Prism:61 +Experimental Aviator:60 +Metallurgic Summonings:60 +Aether Theorist:60 +Rings of Brighthearth:60 +Toolcraft Exemplar:60 +Attune with Aether:60 +Thriving Ibex:59 +Narnam Cobra:59 +Quicksmith Genius:59 +Fabrication Module:59 +Lotus Petal:59 +Thriving Rats:58 +Insidious Will:58 +Embraal Bruiser:58 +Maulfist Squad:58 +Dhund Operative:58 +Cloudstone Curio:58 +Salivating Gremlins:57 +Janjeet Sentry:57 +Static Orb:57 +Era of Innovation:57 +Fairgrounds Trumpeter:57 +Wind Drake:56 +Lawless Broker:56 +Ovalchase Dragster:56 +Fragmentize:56 +Blossoming Defense:56 +Built to Last:56 +Territorial Gorger:55 +Skyswirl Harrier:55 +Rush of Vitality:55 +Wild Wanderer:55 +Deadlock Trap:55 +Spireside Infiltrator:54 +Durable Handicraft:54 +Prakhata Pillar-Bug:54 +Dukhara Peafowl:54 +Sage of Shaila's Claim:54 +Incendiary Sabotage:54 +Weldfast Monitor:53 +Trusty Companion:53 +Iron League Steed:53 +Spark of Creativity:53 +Self-Assembler:53 +Make Obsolete:52 +Select for Inspection:52 +Live Fast:52 +Ambitious Aetherborn:52 +Thriving Turtle:52 +Nimble Innovator:51 +Eager Construct:51 +Servo Exhibition:51 +Appetite for the Unnatural:51 +Midnight Oil:51 +Eddytrail Hawk:50 +Æther Tradewinds:50 +Reckless Fireweaver:50 +Weldfast Wingsmith:50 +Ghirapur Guide:50 +Electrostatic Pummeler:49 +Painter's Servant:49 +Bastion Mastodon:49 +Highspire Artisan:49 +Cathartic Reunion:49 +Wayward Giant:48 +Acrobatic Maneuver:48 +Crucible of Worlds:48 +Built to Smash:48 +Prakhata Club Security:47 +Vedalken Blademaster:47 +Panharmonicon:47 +Decoction Module:47 +Inventor's Apprentice:47 +Fretwork Colony:46 +Hightide Hermit:46 +Spirebluff Canal:46 +Botanical Sanctum:46 +Blooming Marsh:45 +Whirlermaker:45 +Concealed Courtyard:45 +Wildest Dreams:45 +Tezzeret's Ambition:44 +Ninth Bridge Patrol:44 +Metalspinner's Puzzleknot:44 +Inspiring Vantage:44 +Ruinous Gremlin:43 +Inventors' Fair:43 +Herald of the Fair:43 +Hazardous Conditions:43 +Glassblower's Puzzleknot:42 +Hijack:42 +Engineered Might:42 +Bomat Courier:42 +Night Market Lookout:41 +Inventor's Goggles:41 +Cowl Prowler:41 +Dukhara Scavenger:41 +Ornamental Courage:40 +Fortuitous Find:40 +Demolition Stomper:40 +Cogworker's Puzzleknot:39 +Creeping Mold:39 +Aradara Express:39 +Minister of Inquiries:38 +Harsh Scrutiny:38 +Accomplished Automaton:38 +Woodweaver's Puzzleknot:37 +Failed Inspection:37 +Diabolic Tutor:37 +Consulate Skygate:36 +Refurbish:36 +Disappearing Act:36 +Pressure Point:35 +Authority of the Consuls:35 +Workshop Assistant:34 +Inspired Charge:34 +Take Down:34 +Renegade Tactics:33 +Larger Than Life:33 +Revolutionary Rebuff:32 +Ceremonious Rejection:32 +Torch Gauntlet:31 +Fireforger's Puzzleknot:31 +Morbid Curiosity:30 +Ghirapur Orrery:30 +Paradoxical Outcome:29 +Curio Vendor:28 +Aetherflux Reservoir:28 +Start Your Engines:27 +Terror of the Fairgrounds:26 +Demolish:26 +Wily Bandar:25 +Consulate Surveillance:24 +Giant Spectacle:23 +Mind Rot:22 +Lost Legacy:21 +Commencement of Festivities:20 +Sequestered Stash:18 +Madcap Experiment:16 +Tasseled Dromedary:14 +Dramatic Reversal:11 +Perpetual Timepiece:6 +Dubious Challenge:0 \ No newline at end of file From 29e34934d92a3eebda57a36b068fec403f18a08d Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 29 Oct 2018 11:45:37 -0500 Subject: [PATCH 095/167] - Added Hidden Stag and Soul Sculptor. --- Mage.Sets/src/mage/cards/h/HiddenStag.java | 73 +++++++++ Mage.Sets/src/mage/cards/o/OpalAcrolith.java | 71 +-------- Mage.Sets/src/mage/cards/o/OpalTitan.java | 6 +- Mage.Sets/src/mage/cards/s/SoulSculptor.java | 149 ++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 2 + .../ControllerPlaysLandTriggeredAbility.java | 50 ++++++ .../OpponentPlaysLandTriggeredAbility.java | 49 ++++++ .../BecomesEnchantmentSourceEffect.java | 79 ++++++++++ 8 files changed, 405 insertions(+), 74 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/h/HiddenStag.java create mode 100644 Mage.Sets/src/mage/cards/s/SoulSculptor.java create mode 100644 Mage/src/main/java/mage/abilities/common/ControllerPlaysLandTriggeredAbility.java create mode 100644 Mage/src/main/java/mage/abilities/common/OpponentPlaysLandTriggeredAbility.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesEnchantmentSourceEffect.java diff --git a/Mage.Sets/src/mage/cards/h/HiddenStag.java b/Mage.Sets/src/mage/cards/h/HiddenStag.java new file mode 100644 index 0000000000..6083cbaf30 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HiddenStag.java @@ -0,0 +1,73 @@ +package mage.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.ControllerPlaysLandTriggeredAbility; +import mage.abilities.common.OpponentPlaysLandTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.effects.common.continuous.BecomesEnchantmentSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class HiddenStag extends CardImpl { + + public HiddenStag(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); + + // Whenever an opponent plays a land, if Hidden Stag is an enchantment, Hidden Stag becomes a 3/2 Elk Beast creature. + Effect effect = new BecomesCreatureSourceEffect(new ElkBeastToken(), "", Duration.WhileOnBattlefield, true, false); + TriggeredAbility ability = new OpponentPlaysLandTriggeredAbility(Zone.BATTLEFIELD, effect, false); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "Whenever an opponent plays a land, if Hidden Stag is an enchantment, Hidden Stag becomes a 3/2 Elk Beast creature.")); + + // Whenever you play a land, if Hidden Stag is a creature, Hidden Stag becomes an enchantment. + Effect effect2 = new BecomesEnchantmentSourceEffect(); + TriggeredAbility ability2 = new ControllerPlaysLandTriggeredAbility(Zone.BATTLEFIELD, effect2, false); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability2, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_CREATURE), + "Whenever you play a land, if Hidden Stag is a creature, Hidden Stag becomes an enchantment.")); + + } + + public HiddenStag(final HiddenStag card) { + super(card); + } + + @Override + public HiddenStag copy() { + return new HiddenStag(this); + } +} + +class ElkBeastToken extends TokenImpl { + + public ElkBeastToken() { + super("Elk Beast", "3/2 Elk Beast creature"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.ELK); + subtype.add(SubType.BEAST); + power = new MageInt(3); + toughness = new MageInt(2); + } + + public ElkBeastToken(final ElkBeastToken token) { + super(token); + } + + public ElkBeastToken copy() { + return new ElkBeastToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java index 9ffae411bd..5e8e17fbda 100644 --- a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java +++ b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java @@ -2,33 +2,23 @@ package mage.cards.o; import java.util.UUID; import mage.MageInt; -import mage.MageObjectReference; -import mage.abilities.Ability; import mage.abilities.TriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; -import mage.abilities.effects.common.continuous.SourceEffect; +import mage.abilities.effects.common.continuous.BecomesEnchantmentSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.DependencyType; import mage.constants.Duration; -import mage.constants.Layer; -import static mage.constants.Layer.TypeChangingEffects_4; -import mage.constants.Outcome; -import mage.constants.SubLayer; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterSpell; import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.game.permanent.token.TokenImpl; /** @@ -53,7 +43,7 @@ public final class OpalAcrolith extends CardImpl { "Whenever an opponent casts a creature spell, if Opal Acrolith is an enchantment, Opal Acrolith becomes a 2/4 Soldier creature.")); // {0}: Opal Acrolith becomes an enchantment. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesEnchantmentSourceEffect(CardType.ENCHANTMENT), new ManaCostsImpl("{0}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesEnchantmentSourceEffect(), new ManaCostsImpl("{0}"))); } @@ -67,63 +57,6 @@ public final class OpalAcrolith extends CardImpl { } } -class BecomesEnchantmentSourceEffect extends ContinuousEffectImpl implements SourceEffect { - - public BecomesEnchantmentSourceEffect(CardType cardType) { - super(Duration.Custom, Outcome.AddAbility); - staticText = "Opal Acrolith becomes an Enchantment"; - dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); - - } - - public BecomesEnchantmentSourceEffect(final BecomesEnchantmentSourceEffect effect) { - super(effect); - } - - @Override - public BecomesEnchantmentSourceEffect copy() { - return new BecomesEnchantmentSourceEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent permanent = affectedObjectList.get(0).getPermanent(game); - if (permanent != null) { - switch (layer) { - case TypeChangingEffects_4: - if (sublayer == SubLayer.NA) { - permanent.getCardType().clear(); - permanent.getSubtype(game).clear(); - if (!permanent.getCardType().contains(CardType.ENCHANTMENT)) { - permanent.getCardType().add(CardType.ENCHANTMENT); - } - } - break; - } - return true; - } - this.discard(); - return false; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return Layer.TypeChangingEffects_4 == layer; - } - -} - class OpalAcrolithSoldier extends TokenImpl { public OpalAcrolithSoldier() { diff --git a/Mage.Sets/src/mage/cards/o/OpalTitan.java b/Mage.Sets/src/mage/cards/o/OpalTitan.java index 8f9655f1d8..1f215472b7 100644 --- a/Mage.Sets/src/mage/cards/o/OpalTitan.java +++ b/Mage.Sets/src/mage/cards/o/OpalTitan.java @@ -69,7 +69,7 @@ class OpalTitanBecomesCreatureEffect extends ContinuousEffectImpl implements Sou public OpalTitanBecomesCreatureEffect() { super(Duration.WhileOnBattlefield, Outcome.BecomeCreature); - setText(); + staticText = "{this} becomes a 4/4 Giant creature with protection from each of that spell's colors."; this.addDependencyType(DependencyType.BecomeCreature); } @@ -135,10 +135,6 @@ class OpalTitanBecomesCreatureEffect extends ContinuousEffectImpl implements Sou return false; } - private void setText() { - staticText = duration.toString() + " {this} becomes a 4/4 Giant creature with protection from each of that spell's colors"; - } - @Override public boolean hasLayer(Layer layer) { return layer == Layer.PTChangingEffects_7 diff --git a/Mage.Sets/src/mage/cards/s/SoulSculptor.java b/Mage.Sets/src/mage/cards/s/SoulSculptor.java new file mode 100644 index 0000000000..f82ccd16f1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoulSculptor.java @@ -0,0 +1,149 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.DependencyType; +import mage.constants.Duration; +import mage.constants.Layer; +import static mage.constants.Layer.TypeChangingEffects_4; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public final class SoulSculptor extends CardImpl { + + final String rule = "Target creature becomes an enchantment and loses all abilities until a player casts a creature spell."; + + public SoulSculptor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.HUMAN); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {1}{W}, {tap}: Target creature becomes an enchantment and loses all abilities until a player casts a creature spell. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new SoulSculptorEffect(), SoulSculptorCondition.instance, rule), new ManaCostsImpl("{1}{W}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + } + + public SoulSculptor(final SoulSculptor card) { + super(card); + } + + @Override + public SoulSculptor copy() { + return new SoulSculptor(this); + } +} + +class SoulSculptorEffect extends ContinuousEffectImpl { + + public SoulSculptorEffect() { + super(Duration.Custom, Outcome.LoseAbility); + staticText = "target becomes an Enchantment and loses all abilites"; + dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); + dependencyTypes.add(DependencyType.AddingAbility); + + } + + public SoulSculptorEffect(final SoulSculptorEffect effect) { + super(effect); + } + + @Override + public SoulSculptorEffect copy() { + return new SoulSculptorEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); + if (targetPermanent != null) { + affectedObjectList.add(new MageObjectReference(targetPermanent, game)); + } + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + Permanent permanent = affectedObjectList.get(0).getPermanent(game); + if (permanent != null) { + switch (layer) { + case TypeChangingEffects_4: + if (sublayer == SubLayer.NA) { + permanent.getCardType().clear(); + permanent.getSubtype(game).clear(); + if (!permanent.getCardType().contains(CardType.ENCHANTMENT)) { + permanent.getCardType().add(CardType.ENCHANTMENT); + } + } + break; + case AbilityAddingRemovingEffects_6: + if (sublayer == SubLayer.NA) { + permanent.getAbilities().clear(); + } + break; + } + return true; + } + this.discard(); + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return Layer.TypeChangingEffects_4 == layer + || Layer.AbilityAddingRemovingEffects_6 == layer; + } + +} + +enum SoulSculptorCondition implements Condition { + + instance; + + @Override + public boolean apply(Game game, Ability source) { + if (!game.getStack().isEmpty()) { + StackObject stackObject = game.getStack().getFirst(); + if (stackObject != null) { + return !stackObject.getCardType().contains(CardType.CREATURE); + } + } + return true; + } + + @Override + public String toString() { + return "creature spell cast"; + } + +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index f4cabc7989..6f9e580da6 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -164,6 +164,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Hidden Guerrillas", 261, Rarity.UNCOMMON, mage.cards.h.HiddenGuerrillas.class)); cards.add(new SetCardInfo("Hidden Herd", 262, Rarity.RARE, mage.cards.h.HiddenHerd.class)); cards.add(new SetCardInfo("Hidden Spider", 264, Rarity.COMMON, mage.cards.h.HiddenSpider.class)); + cards.add(new SetCardInfo("Hidden Stag", 265, Rarity.RARE, mage.cards.h.HiddenStag.class)); cards.add(new SetCardInfo("Hollow Dogs", 137, Rarity.COMMON, mage.cards.h.HollowDogs.class)); cards.add(new SetCardInfo("Hopping Automaton", 297, Rarity.UNCOMMON, mage.cards.h.HoppingAutomaton.class)); cards.add(new SetCardInfo("Horseshoe Crab", 80, Rarity.COMMON, mage.cards.h.HorseshoeCrab.class)); @@ -295,6 +296,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Sneak Attack", 218, Rarity.RARE, mage.cards.s.SneakAttack.class)); cards.add(new SetCardInfo("Somnophore", 97, Rarity.RARE, mage.cards.s.Somnophore.class)); cards.add(new SetCardInfo("Songstitcher", 52, Rarity.UNCOMMON, mage.cards.s.Songstitcher.class)); + cards.add(new SetCardInfo("Soul Sculptor", 53, Rarity.RARE, mage.cards.s.SoulSculptor.class)); cards.add(new SetCardInfo("Spined Fluke", 160, Rarity.UNCOMMON, mage.cards.s.SpinedFluke.class)); cards.add(new SetCardInfo("Spire Owl", 98, Rarity.COMMON, mage.cards.s.SpireOwl.class)); cards.add(new SetCardInfo("Sporogenesis", 273, Rarity.RARE, mage.cards.s.Sporogenesis.class)); diff --git a/Mage/src/main/java/mage/abilities/common/ControllerPlaysLandTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/ControllerPlaysLandTriggeredAbility.java new file mode 100644 index 0000000000..252203870d --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/ControllerPlaysLandTriggeredAbility.java @@ -0,0 +1,50 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; + +/** + * + * @author jeffwadsworth + */ +public class ControllerPlaysLandTriggeredAbility extends TriggeredAbilityImpl { + + public ControllerPlaysLandTriggeredAbility(Zone zone, Effect effect, Boolean optional) { + super(zone, effect, optional); + } + + public ControllerPlaysLandTriggeredAbility(ControllerPlaysLandTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.LAND_PLAYED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent land = game.getPermanent(event.getTargetId()); + return land.getControllerId().equals(controllerId); + } + + @Override + public ControllerPlaysLandTriggeredAbility copy() { + return new ControllerPlaysLandTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever you play a land, "; + } +} diff --git a/Mage/src/main/java/mage/abilities/common/OpponentPlaysLandTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/OpponentPlaysLandTriggeredAbility.java new file mode 100644 index 0000000000..7249b6679e --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/OpponentPlaysLandTriggeredAbility.java @@ -0,0 +1,49 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author jeffwadsworth + */ +public class OpponentPlaysLandTriggeredAbility extends TriggeredAbilityImpl { + + public OpponentPlaysLandTriggeredAbility(Zone zone, Effect effect, Boolean optional) { + super(zone, effect, optional); + } + + public OpponentPlaysLandTriggeredAbility(OpponentPlaysLandTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.LAND_PLAYED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent land = game.getPermanent(event.getTargetId()); + return game.getOpponents(controllerId).contains(land.getControllerId()); + } + + @Override + public OpponentPlaysLandTriggeredAbility copy() { + return new OpponentPlaysLandTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever an opponent plays a land, "; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesEnchantmentSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesEnchantmentSourceEffect.java new file mode 100644 index 0000000000..e16f3d033a --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesEnchantmentSourceEffect.java @@ -0,0 +1,79 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.effects.common.continuous; + +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.CardType; +import mage.constants.DependencyType; +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; + +/** + * + * @author jeffwadsworth + */ +public class BecomesEnchantmentSourceEffect extends ContinuousEffectImpl implements SourceEffect { + + public BecomesEnchantmentSourceEffect() { + super(Duration.Custom, Outcome.AddAbility); + staticText = "{this} becomes an Enchantment"; + dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); + + } + + public BecomesEnchantmentSourceEffect(final BecomesEnchantmentSourceEffect effect) { + super(effect); + } + + @Override + public BecomesEnchantmentSourceEffect copy() { + return new BecomesEnchantmentSourceEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + Permanent permanent = affectedObjectList.get(0).getPermanent(game); + if (permanent != null) { + switch (layer) { + case TypeChangingEffects_4: + if (sublayer == SubLayer.NA) { + permanent.getCardType().clear(); + permanent.getSubtype(game).clear(); + if (!permanent.getCardType().contains(CardType.ENCHANTMENT)) { + permanent.getCardType().add(CardType.ENCHANTMENT); + } + } + break; + } + return true; + } + this.discard(); + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return Layer.TypeChangingEffects_4 == layer; + } + +} From 369beb213bb3e48e4cc84d00d487723122e775d4 Mon Sep 17 00:00:00 2001 From: davidmfritz Date: Mon, 29 Oct 2018 22:22:24 +0100 Subject: [PATCH 096/167] Fixed Scepter of Empires AA Cost Fixed Scepter of Empires Activated Ability Cost from "{0}, {T}" to "{T}" --- Mage.Sets/src/mage/cards/s/ScepterOfEmpires.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/ScepterOfEmpires.java b/Mage.Sets/src/mage/cards/s/ScepterOfEmpires.java index 5907583eff..8455a23f8b 100644 --- a/Mage.Sets/src/mage/cards/s/ScepterOfEmpires.java +++ b/Mage.Sets/src/mage/cards/s/ScepterOfEmpires.java @@ -5,7 +5,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -25,8 +24,7 @@ public final class ScepterOfEmpires extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // {tap}: Scepter of Empires deals 1 damage to target player. It deals 3 damage to that player instead if you control artifacts named Crown of Empires and Throne of Empires. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScepterOfEmpiresEffect(), new GenericManaCost(0)); - ability.addCost(new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScepterOfEmpiresEffect(), new TapSourceCost()); ability.addTarget(new TargetPlayerOrPlaneswalker()); this.addAbility(ability); } From 4d01c72c3eed5e188087be60b1b3c913a781e2bc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 30 Oct 2018 11:04:38 -0400 Subject: [PATCH 097/167] updated Aus Highlander and Canadian Highlander point lists --- .../src/mage/deck/AusHighlander.java | 10 +++++----- .../src/mage/deck/CanadianHighlander.java | 9 ++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/AusHighlander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/AusHighlander.java index 112563f76d..ed5a331ce3 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/AusHighlander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/AusHighlander.java @@ -1,15 +1,15 @@ package mage.deck; -import java.util.HashMap; -import java.util.Map; import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; import mage.constants.SetType; +import java.util.HashMap; +import java.util.Map; + /** - * * @author spjspj */ public class AusHighlander extends Constructed { @@ -36,9 +36,9 @@ public class AusHighlander extends Constructed { pointMap.put("Dig Through Time", 2); pointMap.put("Library of Alexandria", 2); pointMap.put("Mana Crypt", 2); + pointMap.put("Mind Twist", 2); pointMap.put("Mystical Tutor", 2); pointMap.put("Protean Hulk", 2); - pointMap.put("Skullclamp", 2); pointMap.put("Strip Mine", 2); pointMap.put("Tolarian Academy", 2); pointMap.put("Treasure Cruise", 2); @@ -61,12 +61,12 @@ public class AusHighlander extends Constructed { pointMap.put("Mana Vault", 1); pointMap.put("Memory Jar", 1); pointMap.put("Merchant Scroll", 1); - pointMap.put("Mind Twist", 1); pointMap.put("Mishra’s Workshop", 1); pointMap.put("Natural Order", 1); pointMap.put("Oath of Druids", 1); pointMap.put("Personal Tutor", 1); pointMap.put("Sensei’s Divining Top", 1); + pointMap.put("Skullclamp", 1); pointMap.put("Snapcaster Mage", 1); pointMap.put("Stoneforge Mystic", 1); pointMap.put("Survival of the Fittest", 1); diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java index 23f5c57f2f..89581e8aeb 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java @@ -1,15 +1,15 @@ package mage.deck; -import java.util.HashMap; -import java.util.Map; import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; import mage.constants.SetType; +import java.util.HashMap; +import java.util.Map; + /** - * * @author spjspj */ public class CanadianHighlander extends Constructed { @@ -19,7 +19,7 @@ public class CanadianHighlander extends Constructed { static { pointMap.put("Ancestral Recall", 7); pointMap.put("Balance", 1); - pointMap.put("Birthing Pod", 3); + pointMap.put("Birthing Pod", 2); pointMap.put("Black Lotus", 7); pointMap.put("Demonic Tutor", 3); pointMap.put("Dig Through Time", 1); @@ -27,7 +27,6 @@ public class CanadianHighlander extends Constructed { pointMap.put("Fastbond", 1); pointMap.put("Flash", 7); pointMap.put("Gifts Ungiven", 2); - pointMap.put("Hermit Druid", 1); pointMap.put("Imperial Seal", 1); pointMap.put("Intuition", 1); pointMap.put("Library of Alexandria", 1); From bf8123b7a520c568fe13cd16a993c0913c472e66 Mon Sep 17 00:00:00 2001 From: davidmfritz <> Date: Wed, 31 Oct 2018 22:50:13 +0100 Subject: [PATCH 098/167] Implementation of the card Clear the Land --- Mage.Sets/src/mage/cards/c/ClearTheLand.java | 91 +++++++++++++++++++ Mage.Sets/src/mage/sets/MercadianMasques.java | 1 + 2 files changed, 92 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ClearTheLand.java diff --git a/Mage.Sets/src/mage/cards/c/ClearTheLand.java b/Mage.Sets/src/mage/cards/c/ClearTheLand.java new file mode 100644 index 0000000000..45c621021e --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ClearTheLand.java @@ -0,0 +1,91 @@ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Library; +import mage.players.Player; +import mage.players.Players; + +/** + * + * @author davidmfritz + */ +public final class ClearTheLand extends CardImpl { + + public ClearTheLand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); + + + // Each player reveals the top five cards of his or her library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest. + getSpellAbility().addEffect(new ClearTheLandEffect()); + } + + public ClearTheLand(final ClearTheLand card) { + super(card); + } + + @Override + public ClearTheLand copy() { + return new ClearTheLand(this); + } +} + +class ClearTheLandEffect extends OneShotEffect { + + public ClearTheLandEffect() { + super(Outcome.Benefit); + this.staticText = "Each player reveals the top five cards of his or her library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest."; + } + + public ClearTheLandEffect(final ClearTheLandEffect effect) { + super(effect); + } + + @Override + public ClearTheLandEffect copy() { + return new ClearTheLandEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + + int numOfCardsToReveal = 5; + boolean tapped = true; + + Player controller = game.getPlayer(source.getControllerId()); + + if (controller != null) { + Players allPlayers = game.getPlayers(); + for (Player player : allPlayers.values()) { + if (player != null) { + Library library = player.getLibrary(); + Cards cardsToReveal = new CardsImpl(); + for (int i = 0; i < numOfCardsToReveal; i++) { + if (library.hasCards()) { + Card card = library.getFromTop(game); + cardsToReveal.add(card); + if (card.isLand()) { + player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null); + } else { + player.moveCards(card, Zone.EXILED, source, game); + } + } + } + player.revealCards(source, "Revealed cards for " + player.getName(), cardsToReveal, game); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/MercadianMasques.java b/Mage.Sets/src/mage/sets/MercadianMasques.java index a1110e968c..aa70db5e8a 100644 --- a/Mage.Sets/src/mage/sets/MercadianMasques.java +++ b/Mage.Sets/src/mage/sets/MercadianMasques.java @@ -75,6 +75,7 @@ public final class MercadianMasques extends ExpansionSet { cards.add(new SetCardInfo("Cho-Manno, Revolutionary", 11, Rarity.RARE, mage.cards.c.ChoMannoRevolutionary.class)); cards.add(new SetCardInfo("Cho-Manno's Blessing", 12, Rarity.COMMON, mage.cards.c.ChoMannosBlessing.class)); cards.add(new SetCardInfo("Cinder Elemental", 183, Rarity.UNCOMMON, mage.cards.c.CinderElemental.class)); + cards.add(new SetCardInfo("Clear the Land", 235, Rarity.RARE, mage.cards.c.ClearTheLand.class)); cards.add(new SetCardInfo("Close Quarters", 184, Rarity.UNCOMMON, mage.cards.c.CloseQuarters.class)); cards.add(new SetCardInfo("Cloud Sprite", 67, Rarity.COMMON, mage.cards.c.CloudSprite.class)); cards.add(new SetCardInfo("Coastal Piracy", 68, Rarity.UNCOMMON, mage.cards.c.CoastalPiracy.class)); From 336732eba28cd53c5031334bb0b316280ead3f40 Mon Sep 17 00:00:00 2001 From: davidmfritz Date: Wed, 31 Oct 2018 23:27:16 +0100 Subject: [PATCH 099/167] Performance fix to get out of the loop quicker if library is empty --- Mage.Sets/src/mage/cards/c/ClearTheLand.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ClearTheLand.java b/Mage.Sets/src/mage/cards/c/ClearTheLand.java index 45c621021e..1bc1f4ad01 100644 --- a/Mage.Sets/src/mage/cards/c/ClearTheLand.java +++ b/Mage.Sets/src/mage/cards/c/ClearTheLand.java @@ -71,14 +71,15 @@ class ClearTheLandEffect extends OneShotEffect { Library library = player.getLibrary(); Cards cardsToReveal = new CardsImpl(); for (int i = 0; i < numOfCardsToReveal; i++) { - if (library.hasCards()) { - Card card = library.getFromTop(game); - cardsToReveal.add(card); - if (card.isLand()) { - player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null); - } else { - player.moveCards(card, Zone.EXILED, source, game); - } + if (!library.hasCards()) { + break; + } + Card card = library.getFromTop(game); + cardsToReveal.add(card); + if (card.isLand()) { + player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null); + } else { + player.moveCards(card, Zone.EXILED, source, game); } } player.revealCards(source, "Revealed cards for " + player.getName(), cardsToReveal, game); From 1dc421a545bac0d0f67726206986f2c6579f342c Mon Sep 17 00:00:00 2001 From: davidmfritz Date: Thu, 1 Nov 2018 10:13:57 +0100 Subject: [PATCH 100/167] Fixed to get the correct player list Refactor to reveal first, then take action --- Mage.Sets/src/mage/cards/c/ClearTheLand.java | 26 +++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ClearTheLand.java b/Mage.Sets/src/mage/cards/c/ClearTheLand.java index 1bc1f4ad01..13b9be2f02 100644 --- a/Mage.Sets/src/mage/cards/c/ClearTheLand.java +++ b/Mage.Sets/src/mage/cards/c/ClearTheLand.java @@ -14,7 +14,6 @@ import mage.constants.Zone; import mage.game.Game; import mage.players.Library; import mage.players.Player; -import mage.players.Players; /** * @@ -59,30 +58,27 @@ class ClearTheLandEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - int numOfCardsToReveal = 5; boolean tapped = true; Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Players allPlayers = game.getPlayers(); - for (Player player : allPlayers.values()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); if (player != null) { Library library = player.getLibrary(); Cards cardsToReveal = new CardsImpl(); - for (int i = 0; i < numOfCardsToReveal; i++) { - if (!library.hasCards()) { - break; - } - Card card = library.getFromTop(game); - cardsToReveal.add(card); - if (card.isLand()) { - player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null); - } else { - player.moveCards(card, Zone.EXILED, source, game); + cardsToReveal.addAll(library.getTopCards(game, 5)); + if (!cardsToReveal.isEmpty()) { + player.revealCards(source, "Revealed cards for " + player.getName(), cardsToReveal, game); + for (Card card : cardsToReveal.getCards(game)) { + if (card.isLand()) { + player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null); + } else { + player.moveCards(card, Zone.EXILED, source, game); + } } } - player.revealCards(source, "Revealed cards for " + player.getName(), cardsToReveal, game); } } return true; From c37832944ea9ec003dba0f792e614067e885b802 Mon Sep 17 00:00:00 2001 From: davidmfritz Date: Thu, 1 Nov 2018 11:51:36 +0100 Subject: [PATCH 101/167] Fixed cards to put onto the battlefield to one call Fixed cards to put into exile to one call --- Mage.Sets/src/mage/cards/c/ClearTheLand.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ClearTheLand.java b/Mage.Sets/src/mage/cards/c/ClearTheLand.java index 13b9be2f02..abb2b34557 100644 --- a/Mage.Sets/src/mage/cards/c/ClearTheLand.java +++ b/Mage.Sets/src/mage/cards/c/ClearTheLand.java @@ -71,13 +71,17 @@ class ClearTheLandEffect extends OneShotEffect { cardsToReveal.addAll(library.getTopCards(game, 5)); if (!cardsToReveal.isEmpty()) { player.revealCards(source, "Revealed cards for " + player.getName(), cardsToReveal, game); + Cards cardsToPutOnBattlefield = new CardsImpl(); + Cards cardsToExile = new CardsImpl(); for (Card card : cardsToReveal.getCards(game)) { if (card.isLand()) { - player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null); + cardsToPutOnBattlefield.add(card); } else { - player.moveCards(card, Zone.EXILED, source, game); + cardsToExile.add(card); } } + player.moveCards(cardsToPutOnBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, tapped, false, true, null); + player.moveCards(cardsToExile.getCards(game), Zone.EXILED, source, game); } } } From 4c56baac032d0d7c6eb4f6528b67eeaaa34d98a0 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 1 Nov 2018 18:18:14 -0500 Subject: [PATCH 102/167] - Fixed #5392 --- Mage.Sets/src/mage/cards/p/Portcullis.java | 90 ++++++++++++++++------ 1 file changed, 67 insertions(+), 23 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/Portcullis.java b/Mage.Sets/src/mage/cards/p/Portcullis.java index c238942678..5a5f9ae600 100644 --- a/Mage.Sets/src/mage/cards/p/Portcullis.java +++ b/Mage.Sets/src/mage/cards/p/Portcullis.java @@ -2,24 +2,30 @@ package mage.cards.p; import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; -import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnFromExileForSourceEffect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; /** @@ -34,14 +40,14 @@ public final class Portcullis extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature. - String rule = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature"; - TriggeredAbility ability = new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new PortcullisExileEffect(), filter, false, SetTargetPointer.PERMANENT, rule); - MoreThanXCreaturesOnBFCondition condition = new MoreThanXCreaturesOnBFCondition(2); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, condition, rule)); - // Return that card to the battlefield under its owner's control when Portcullis leaves the battlefield. - Ability ability2 = new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false); - this.addAbility(ability2); + String rule = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature."; + String rule2 = " Return that card to the battlefield under its owner's control when {this} leaves the battlefield."; + TriggeredAbility ability = new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new PortcullisExileEffect(), + filter, false, SetTargetPointer.PERMANENT, rule); + MoreThanXCreaturesOnBFCondition condition = new MoreThanXCreaturesOnBFCondition(2); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, condition, rule + rule2)); + } public Portcullis(final Portcullis card) { @@ -74,8 +80,8 @@ class MoreThanXCreaturesOnBFCondition implements Condition { class PortcullisExileEffect extends OneShotEffect { public PortcullisExileEffect() { - super(Outcome.Neutral); - this.staticText = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature."; + super(Outcome.Exile); + this.staticText = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature"; } public PortcullisExileEffect(final PortcullisExileEffect effect) { @@ -89,20 +95,58 @@ class PortcullisExileEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent creature = game.getPermanent(targetPointer.getFirst(game, source)); - - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - permanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); + Permanent creatureToExile = game.getPermanent(getTargetPointer().getFirst(game, source)); + Permanent portcullis = game.getPermanent(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (portcullis != null + && creatureToExile != null + && controller != null) { + UUID exileZoneId = CardUtil.getExileZoneId(game, creatureToExile.getId(), creatureToExile.getZoneChangeCounter(game)); + controller.moveCardsToExile(creatureToExile, source, game, true, exileZoneId, portcullis.getName()); + FixedTarget fixedTarget = new FixedTarget(portcullis, game); + Effect returnEffect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(); + returnEffect.setTargetPointer(new FixedTarget(creatureToExile.getId(), game.getState().getZoneChangeCounter(creatureToExile.getId()))); + DelayedTriggeredAbility delayedAbility = new PortcullisReturnToBattlefieldTriggeredAbility(fixedTarget, returnEffect); + game.addDelayedTriggeredAbility(delayedAbility, source); } - if (permanent != null && creature != null) { - Player controller = game.getPlayer(creature.getControllerId()); - Zone currentZone = game.getState().getZone(creature.getId()); - if (currentZone == Zone.BATTLEFIELD) { - controller.moveCardsToExile(creature, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName()); - return true; - } + return true; + } +} + +class PortcullisReturnToBattlefieldTriggeredAbility extends DelayedTriggeredAbility { + + protected FixedTarget fixedTarget; + + public PortcullisReturnToBattlefieldTriggeredAbility(FixedTarget fixedTarget, Effect effect) { + super(effect, Duration.OneUse); + this.fixedTarget = fixedTarget; + } + + public PortcullisReturnToBattlefieldTriggeredAbility(final PortcullisReturnToBattlefieldTriggeredAbility ability) { + super(ability); + this.fixedTarget = ability.fixedTarget; + } + + @Override + public PortcullisReturnToBattlefieldTriggeredAbility copy() { + return new PortcullisReturnToBattlefieldTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (((ZoneChangeEvent) event).getFromZone().match(Zone.BATTLEFIELD)) { + return (fixedTarget.getTarget().equals(event.getTargetId())); } return false; } + + @Override + public String getRule() { + return "Return this card to the battlefield under its owner's control when Portcullis leaves the battlefield."; + } } From c9719488ca95f01975bed5e72f0980c1504e464b Mon Sep 17 00:00:00 2001 From: John Hitchings Date: Sun, 4 Nov 2018 11:19:16 -0800 Subject: [PATCH 103/167] Fix GAME_CHOOSE_ABILITY event submitted to appendJsonEvent. --- .../src/main/java/mage/client/remote/CallbackClientImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java index f71b122591..f3bc3dc5d2 100644 --- a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java +++ b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java @@ -214,7 +214,7 @@ public class CallbackClientImpl implements CallbackClient { case GAME_CHOOSE_ABILITY: { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { - appendJsonEvent("GAME_CHOOSE_PILE", callback.getObjectId(), callback.getData()); + appendJsonEvent("GAME_CHOOSE_ABILITY", callback.getObjectId(), callback.getData()); panel.pickAbility((AbilityPickerView) callback.getData()); } break; From a399f94bb1d30a25f01dc3bc86bce11bb2564bb7 Mon Sep 17 00:00:00 2001 From: brodee Date: Sun, 4 Nov 2018 20:31:45 -0800 Subject: [PATCH 104/167] fixed: Earthsurge should affect all players --- Mage.Sets/src/mage/cards/e/EarthSurge.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/e/EarthSurge.java b/Mage.Sets/src/mage/cards/e/EarthSurge.java index 4f82004c4c..6992e2695a 100644 --- a/Mage.Sets/src/mage/cards/e/EarthSurge.java +++ b/Mage.Sets/src/mage/cards/e/EarthSurge.java @@ -4,7 +4,7 @@ package mage.cards.e; import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -29,7 +29,7 @@ public final class EarthSurge extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}"); //Each land gets +2/+2 as long as it's a creature. - Effect effect = new BoostControlledEffect(2, 2, Duration.WhileOnBattlefield, filter, true); + Effect effect = new BoostAllEffect(2, 2, Duration.WhileOnBattlefield, filter, true); effect.setText("Each land gets +2/+2 as long as it\'s a creature"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } From a806e79abd3ef68e9947b25d95d82923ca63befb Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 5 Nov 2018 09:06:31 +0400 Subject: [PATCH 105/167] * Improved chat help about ignore command (it's not only chat, but game joins too); --- Mage.Client/src/main/java/mage/client/util/IgnoreList.java | 4 ++-- Mage.Server/src/main/java/mage/server/ChatManager.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/util/IgnoreList.java b/Mage.Client/src/main/java/mage/client/util/IgnoreList.java index 89906031fa..3fbabab31d 100644 --- a/Mage.Client/src/main/java/mage/client/util/IgnoreList.java +++ b/Mage.Client/src/main/java/mage/client/util/IgnoreList.java @@ -9,8 +9,8 @@ import mage.view.ChatMessage; public final class IgnoreList { - private static final String USAGE = "
\\ignore - shows current ignore list on this server." - + "
\\ignore [username] - add a username to your ignore list on this server." + private static final String USAGE = "
\\ignore - shows your ignore list on this server." + + "
\\ignore [username] - add username to ignore list (they won't be able to chat or join to your game)." + "
\\unignore [username] - remove a username from your ignore list on this server.
"; public static final int MAX_IGNORE_LIST_SIZE = 50; diff --git a/Mage.Server/src/main/java/mage/server/ChatManager.java b/Mage.Server/src/main/java/mage/server/ChatManager.java index 4841a76643..7ef083002a 100644 --- a/Mage.Server/src/main/java/mage/server/ChatManager.java +++ b/Mage.Server/src/main/java/mage/server/ChatManager.java @@ -172,8 +172,8 @@ public enum ChatManager { + "
\\whisper or \\w [player name] [text] - whisper to the player with the given name" + "
\\card Card Name - Print oracle text for card" + "
[Card Name] - Show a highlighted card name" - + "
\\ignore - shows current ignore list on this server." - + "
\\ignore [username] - add a username to your ignore list on this server." + + "
\\ignore - shows your ignore list on this server." + + "
\\ignore [username] - add username to ignore list (they won't be able to chat or join to your game)." + "
\\unignore [username] - remove a username from your ignore list on this server."; final Pattern getCardTextPattern = Pattern.compile("^.card *(.*)"); From 706ed23bdc46c9f1df7ae0ba05d2592bcf12efb9 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 5 Nov 2018 09:28:24 +0400 Subject: [PATCH 106/167] * Added ignored list to tournaments (users from ignored list can't join to your tournaments too); --- .../src/main/java/mage/client/dialog/NewTournamentDialog.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java index f5f2961f51..ee0d5aded5 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java @@ -24,6 +24,7 @@ import mage.cards.repository.ExpansionRepository; import mage.client.MageFrame; import mage.client.SessionHandler; import mage.client.table.TournamentPlayerPanel; +import mage.client.util.IgnoreList; import mage.client.util.gui.FastSearchUtil; import mage.constants.MatchTimeLimit; import mage.constants.MultiplayerAttackOption; @@ -595,6 +596,9 @@ public class NewTournamentDialog extends MageDialog { tOptions.getMatchOptions().setLimited(false); } + String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); + tOptions.getMatchOptions().setBannedUsers(IgnoreList.ignoreList(serverAddress)); + tOptions.getMatchOptions().setMatchTimeLimit((MatchTimeLimit) this.cbTimeLimit.getSelectedItem()); tOptions.getMatchOptions().setSkillLevel((SkillLevel) this.cbSkillLevel.getSelectedItem()); tOptions.getMatchOptions().setWinsNeeded((Integer) this.spnNumWins.getValue()); From 5a6bed313d916cdabdb9292a6cd3b683809033d0 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 5 Nov 2018 09:21:17 -0600 Subject: [PATCH 107/167] - Fixed #5409 --- Mage.Sets/src/mage/cards/g/GripOfChaos.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/g/GripOfChaos.java b/Mage.Sets/src/mage/cards/g/GripOfChaos.java index 3cbd36bc98..479a74548d 100644 --- a/Mage.Sets/src/mage/cards/g/GripOfChaos.java +++ b/Mage.Sets/src/mage/cards/g/GripOfChaos.java @@ -126,7 +126,10 @@ class GripOfChaosEffect extends OneShotEffect { Mode mode = stackObject.getStackAbility().getModes().get(modeId); for (Target target : mode.getTargets()) { UUID oldTargetId = target.getFirstTarget(); - Set possibleTargets = target.possibleTargets(stackObject.getSourceId(), stackObject.getControllerId(), game); + Set possibleTargets = target.possibleTargets(stackObject.getId(), stackObject.getControllerId(), game); + if (possibleTargets.contains(stackObject.getId())) { // The stackObject can't target itself + possibleTargets.remove(stackObject.getId()); + } if (!possibleTargets.isEmpty()) { int i = 0; int rnd = RandomUtil.nextInt(possibleTargets.size()); From a3206785abc897c436bc870f72d12a1e2e7fea7e Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 5 Nov 2018 11:02:58 -0600 Subject: [PATCH 108/167] - Fixed #5410 --- Mage.Sets/src/mage/cards/t/TemurWarShaman.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/t/TemurWarShaman.java b/Mage.Sets/src/mage/cards/t/TemurWarShaman.java index c95e2f8279..96577ada39 100644 --- a/Mage.Sets/src/mage/cards/t/TemurWarShaman.java +++ b/Mage.Sets/src/mage/cards/t/TemurWarShaman.java @@ -14,6 +14,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.TargetController; +import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; @@ -62,7 +63,7 @@ public final class TemurWarShaman extends CardImpl { class TemurWarShamanTriggeredAbility extends TurnedFaceUpAllTriggeredAbility { public TemurWarShamanTriggeredAbility() { - super(new TemurWarShamanFightEffect(), new FilterControlledCreaturePermanent(), true); + super(Zone.BATTLEFIELD, new TemurWarShamanFightEffect(), new FilterControlledCreaturePermanent(), true, true); } public TemurWarShamanTriggeredAbility(final TemurWarShamanTriggeredAbility ability) { From baeb9d8b0089d733cea0b941a02e9aa6e6707476 Mon Sep 17 00:00:00 2001 From: John Hitchings Date: Thu, 8 Nov 2018 09:25:03 -0800 Subject: [PATCH 109/167] Prepopulate DeckImportFromClipboardDialog content with string contents of clipboard. --- .../deckeditor/DeckImportFromClipboardDialog.java | 15 +++++++++++++++ .../cards/decks/importer/DeckImporterUtil.java | 4 +++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java index eef1987dfa..6c89063217 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java @@ -3,11 +3,15 @@ package mage.client.deckeditor; import mage.util.StreamUtils; import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.*; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.Optional; + import javax.swing.*; public class DeckImportFromClipboardDialog extends JDialog { @@ -38,6 +42,17 @@ public class DeckImportFromClipboardDialog extends JDialog { // Close on "ESC" contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + getClipboardStringData().ifPresent(content -> txtDeckList.setText(content)); + } + + private Optional getClipboardStringData() { + try { + return Optional.of((String)Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor)); + } catch (HeadlessException | UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + } + return Optional.empty(); } private void onOK() { diff --git a/Mage/src/main/java/mage/cards/decks/importer/DeckImporterUtil.java b/Mage/src/main/java/mage/cards/decks/importer/DeckImporterUtil.java index a0e90dc526..0384a17f44 100644 --- a/Mage/src/main/java/mage/cards/decks/importer/DeckImporterUtil.java +++ b/Mage/src/main/java/mage/cards/decks/importer/DeckImporterUtil.java @@ -39,7 +39,9 @@ public final class DeckImporterUtil { } public static DeckImporter getDeckImporter(String file) { - if (file.toLowerCase(Locale.ENGLISH).endsWith("dec")) { + if (file == null) { + return null; + } if (file.toLowerCase(Locale.ENGLISH).endsWith("dec")) { return new DecDeckImporter(); } else if (file.toLowerCase(Locale.ENGLISH).endsWith("mwdeck")) { return new MWSDeckImporter(); From 61fb31bea0541f3bd9addfbcc5de4d9db200cd12 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 8 Nov 2018 17:54:05 -0600 Subject: [PATCH 110/167] - Added Serra's Hymn and Venomous Fangs. --- Mage.Sets/src/mage/cards/s/SerrasHymn.java | 55 +++++++++++++++++++ Mage.Sets/src/mage/cards/v/VenomousFangs.java | 48 ++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 3 + ...reventDamageToTargetMultiAmountEffect.java | 18 ++++-- 4 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SerrasHymn.java create mode 100644 Mage.Sets/src/mage/cards/v/VenomousFangs.java diff --git a/Mage.Sets/src/mage/cards/s/SerrasHymn.java b/Mage.Sets/src/mage/cards/s/SerrasHymn.java new file mode 100644 index 0000000000..5d7b9be30b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SerrasHymn.java @@ -0,0 +1,55 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.PreventDamageToTargetMultiAmountEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +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.counters.CounterType; +import mage.target.common.TargetAnyTargetAmount; + +/** + * + * @author jeffwadsworth + */ +public final class SerrasHymn extends CardImpl { + + private static final String rule = "Prevent the next X damage that would be dealt this turn to any number of target creatures and/or players, divided as you choose, where X is the number of verse counters on {this}."; + + public SerrasHymn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); + + // At the beginning of your upkeep, you may put a verse counter on Serra's Hymn. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true)); + + // Sacrifice Serra's Hymn: Prevent the next X damage that would be dealt this turn to any number of target creatures and/or players, divided as you choose, where X is the number of verse counters on Serra's Hymn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new PreventDamageToTargetMultiAmountEffect( + Duration.EndOfTurn, + 1, false, true, // the integer 1 is ignored due to the dynamic number being set + new CountersSourceCount(CounterType.VERSE)).setText(rule), + new SacrificeSourceCost()); + ability.addTarget(new TargetAnyTargetAmount(new CountersSourceCount(CounterType.VERSE))); + this.addAbility(ability); + + } + + public SerrasHymn(final SerrasHymn card) { + super(card); + } + + @Override + public SerrasHymn copy() { + return new SerrasHymn(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VenomousFangs.java b/Mage.Sets/src/mage/cards/v/VenomousFangs.java new file mode 100644 index 0000000000..1be68f955f --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VenomousFangs.java @@ -0,0 +1,48 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToACreatureAttachedTriggeredAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author jeffwadsworth + */ +public final class VenomousFangs extends CardImpl { + + public VenomousFangs(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Whenever enchanted creature deals damage to a creature, destroy the other creature. + this.addAbility(new DealsDamageToACreatureAttachedTriggeredAbility(new DestroyTargetEffect(), false, "enchanted creature", false, true)); + + } + + public VenomousFangs(final VenomousFangs card) { + super(card); + } + + @Override + public VenomousFangs copy() { + return new VenomousFangs(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 6f9e580da6..5650f72e53 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -275,9 +275,11 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Seasoned Marshal", 44, Rarity.UNCOMMON, mage.cards.s.SeasonedMarshal.class)); cards.add(new SetCardInfo("Serra Avatar", 45, Rarity.RARE, mage.cards.s.SerraAvatar.class)); cards.add(new SetCardInfo("Serra's Embrace", 47, Rarity.UNCOMMON, mage.cards.s.SerrasEmbrace.class)); + cards.add(new SetCardInfo("Serra's Hymn", 48, Rarity.UNCOMMON, mage.cards.s.SerrasHymn.class)); cards.add(new SetCardInfo("Serra's Liturgy", 49, Rarity.RARE, mage.cards.s.SerrasLiturgy.class)); cards.add(new SetCardInfo("Serra's Sanctum", 325, Rarity.RARE, mage.cards.s.SerrasSanctum.class)); cards.add(new SetCardInfo("Serra Zealot", 46, Rarity.COMMON, mage.cards.s.SerraZealot.class)); + cards.add(new SetCardInfo("Serra's Hymn", 48, Rarity.UNCOMMON, mage.cards.s.SerrasHymn.class)); cards.add(new SetCardInfo("Shimmering Barrier", 50, Rarity.UNCOMMON, mage.cards.s.ShimmeringBarrier.class)); cards.add(new SetCardInfo("Shivan Gorge", 326, Rarity.RARE, mage.cards.s.ShivanGorge.class)); cards.add(new SetCardInfo("Shivan Hellkite", 214, Rarity.RARE, mage.cards.s.ShivanHellkite.class)); @@ -332,6 +334,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Urza's Armor", 313, Rarity.UNCOMMON, mage.cards.u.UrzasArmor.class)); cards.add(new SetCardInfo("Vampiric Embrace", 164, Rarity.UNCOMMON, mage.cards.v.VampiricEmbrace.class)); cards.add(new SetCardInfo("Vebulid", 165, Rarity.RARE, mage.cards.v.Vebulid.class)); + cards.add(new SetCardInfo("Venomous Fangs", 280, Rarity.COMMON, mage.cards.v.VenomousFangs.class)); cards.add(new SetCardInfo("Vernal Bloom", 281, Rarity.RARE, mage.cards.v.VernalBloom.class)); cards.add(new SetCardInfo("Viashino Outrider", 223, Rarity.COMMON, mage.cards.v.ViashinoOutrider.class)); cards.add(new SetCardInfo("Viashino Runner", 224, Rarity.COMMON, mage.cards.v.ViashinoRunner.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetMultiAmountEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetMultiAmountEffect.java index b72b54d01c..0e832aeac6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetMultiAmountEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetMultiAmountEffect.java @@ -6,6 +6,7 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; +import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.PreventionEffectImpl; import mage.constants.Duration; import mage.game.Game; @@ -27,6 +28,10 @@ public class PreventDamageToTargetMultiAmountEffect extends PreventionEffectImpl super(duration, amount, false); } + public PreventDamageToTargetMultiAmountEffect(Duration duration, int amount, boolean onlyCombat, boolean consumable, DynamicValue dynamicValue) { + super(duration, amount, onlyCombat, consumable, dynamicValue); + } + public PreventDamageToTargetMultiAmountEffect(final PreventDamageToTargetMultiAmountEffect effect) { super(effect); } @@ -100,12 +105,15 @@ public class PreventDamageToTargetMultiAmountEffect extends PreventionEffectImpl @Override public String getText(Mode mode) { StringBuilder sb = new StringBuilder(); - sb.append("prevent the next ").append(amountToPrevent).append(" damage that would be dealt "); - if (duration == Duration.EndOfTurn) { - sb.append("this turn "); + if (staticText.isEmpty()) { + sb.append("prevent the next ").append(amountToPrevent).append(" damage that would be dealt "); + if (duration == Duration.EndOfTurn) { + sb.append("this turn "); + } + sb.append("to any number of targets, divided as you choose"); + return sb.toString(); } - sb.append("to any number of targets, divided as you choose"); - return sb.toString(); + return staticText; } } From 45bb2a12fdf1b10d71ee3510f0e375bd4ea58559 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 9 Nov 2018 20:56:19 +0400 Subject: [PATCH 111/167] Fixed card name duplicate --- Mage.Sets/src/mage/sets/UrzasSaga.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 5650f72e53..a9945c10fc 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -279,7 +279,6 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Serra's Liturgy", 49, Rarity.RARE, mage.cards.s.SerrasLiturgy.class)); cards.add(new SetCardInfo("Serra's Sanctum", 325, Rarity.RARE, mage.cards.s.SerrasSanctum.class)); cards.add(new SetCardInfo("Serra Zealot", 46, Rarity.COMMON, mage.cards.s.SerraZealot.class)); - cards.add(new SetCardInfo("Serra's Hymn", 48, Rarity.UNCOMMON, mage.cards.s.SerrasHymn.class)); cards.add(new SetCardInfo("Shimmering Barrier", 50, Rarity.UNCOMMON, mage.cards.s.ShimmeringBarrier.class)); cards.add(new SetCardInfo("Shivan Gorge", 326, Rarity.RARE, mage.cards.s.ShivanGorge.class)); cards.add(new SetCardInfo("Shivan Hellkite", 214, Rarity.RARE, mage.cards.s.ShivanHellkite.class)); From 20fe92b98becc76b3a97b78851b59cadb7bbe154 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sun, 11 Nov 2018 22:04:48 +0400 Subject: [PATCH 112/167] * Machinate - fixed wrong card text; --- Mage.Sets/src/mage/cards/m/Machinate.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/m/Machinate.java b/Mage.Sets/src/mage/cards/m/Machinate.java index dbb2094a56..b1039219f0 100644 --- a/Mage.Sets/src/mage/cards/m/Machinate.java +++ b/Mage.Sets/src/mage/cards/m/Machinate.java @@ -30,7 +30,9 @@ public final class Machinate extends CardImpl { // Look at the top X cards of your library, where X is the number of artifacts you control. Put one of those cards into your hand and the rest on the bottom of your library in any order. DynamicValue artifactsOnControl = new PermanentsOnBattlefieldCount(filter); - this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(artifactsOnControl, false, new StaticValue(1), new FilterCard(), Zone.LIBRARY, false, false)); + LookLibraryAndPickControllerEffect effect = new LookLibraryAndPickControllerEffect(artifactsOnControl, false, new StaticValue(1), new FilterCard(), Zone.LIBRARY, false, false); + effect.setText("Look at the top X cards of your library, where X is the number of artifacts you control. Put one of those cards into your hand and the rest on the bottom of your library in any order."); + this.getSpellAbility().addEffect(effect); } public Machinate(final Machinate card) { From fe3eda494489c5fd3ff73c1b3669c485187e3250 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sun, 11 Nov 2018 22:54:49 +0400 Subject: [PATCH 113/167] * Spell Contortion, Warleader's Helix - fixed wrong card text; Removed unused getRules in cards code; --- Mage.Sets/src/mage/cards/s/SpellContortion.java | 14 +++----------- Mage.Sets/src/mage/cards/w/WarleadersHelix.java | 14 +++----------- .../test/java/mage/verify/VerifyCardDataTest.java | 15 +++++++++++---- .../common/DrawCardSourceControllerEffect.java | 3 ++- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SpellContortion.java b/Mage.Sets/src/mage/cards/s/SpellContortion.java index 208f327bd2..aab49c9ab4 100644 --- a/Mage.Sets/src/mage/cards/s/SpellContortion.java +++ b/Mage.Sets/src/mage/cards/s/SpellContortion.java @@ -4,6 +4,7 @@ package mage.cards.s; import java.util.ArrayList; import java.util.List; import java.util.UUID; + import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.dynamicvalue.common.MultikickerCount; import mage.abilities.effects.common.CounterUnlessPaysEffect; @@ -15,23 +16,21 @@ import mage.constants.CardType; import mage.target.TargetSpell; /** - * * @author jeffwadsworth */ public final class SpellContortion extends CardImpl { public SpellContortion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); // Multikicker {1}{U} this.addAbility(new MultikickerAbility("{1}{U}")); - + // Counter target spell unless its controller pays {2}. Draw a card for each time Spell Contortion was kicked. this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new GenericManaCost(2))); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new MultikickerCount())); this.getSpellAbility().addTarget(new TargetSpell()); - } public SpellContortion(final SpellContortion card) { @@ -42,11 +41,4 @@ public final class SpellContortion extends CardImpl { public SpellContortion copy() { return new SpellContortion(this); } - - @Override - public List getRules() { - List rules = new ArrayList<>(); - rules.add("Counter target spell unless its controller pays {2}. Draw a card for each time Spell Contortion was kicked."); - return rules; - } } diff --git a/Mage.Sets/src/mage/cards/w/WarleadersHelix.java b/Mage.Sets/src/mage/cards/w/WarleadersHelix.java index 77b2feb5dd..769228823d 100644 --- a/Mage.Sets/src/mage/cards/w/WarleadersHelix.java +++ b/Mage.Sets/src/mage/cards/w/WarleadersHelix.java @@ -4,6 +4,7 @@ package mage.cards.w; import java.util.ArrayList; import java.util.List; import java.util.UUID; + import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; @@ -12,18 +13,16 @@ import mage.constants.CardType; import mage.target.common.TargetAnyTarget; /** - * * @author jeffwadsworth */ public final class WarleadersHelix extends CardImpl { public WarleadersHelix(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}{W}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}{W}"); // Warleader's Helix deals 4 damage to any target and you gain 4 life. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); - this.getSpellAbility().addEffect(new GainLifeEffect(4)); + this.getSpellAbility().addEffect(new GainLifeEffect(4).setText("and you gain 4 life")); this.getSpellAbility().addTarget(new TargetAnyTarget()); } @@ -35,11 +34,4 @@ public final class WarleadersHelix extends CardImpl { public WarleadersHelix copy() { return new WarleadersHelix(this); } - - @Override - public List getRules() { - List rules = new ArrayList<>(); - rules.add("Warleader's Helix deals 4 damage to any target and you gain 4 life."); - return rules; - } } diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 34869ff85b..991315438a 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -1,15 +1,17 @@ package mage.verify; import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.keyword.MultikickerAbility; import mage.cards.*; import mage.cards.basiclands.BasicLand; +import mage.cards.repository.CardRepository; +import mage.cards.repository.CardScanner; import mage.constants.CardType; -import mage.constants.Constants; import mage.constants.Rarity; import mage.constants.SuperType; import mage.game.permanent.token.Token; import mage.game.permanent.token.TokenImpl; -import mage.util.CardUtil; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -381,9 +383,9 @@ public class VerifyCardDataTest { // check for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { boolean cardHaveDoubleName = (doubleNames.getOrDefault(card.getName(), 0) > 1); - boolean cardHaveVariousSetting = card.getGraphicInfo() == null ? false : card.getGraphicInfo().getUsesVariousArt(); + boolean cardHaveVariousSetting = card.getGraphicInfo() == null ? false : card.getGraphicInfo().getUsesVariousArt(); - if(cardHaveDoubleName && !cardHaveVariousSetting) { + if (cardHaveDoubleName && !cardHaveVariousSetting) { errorsList.add("error, founded double card names, but UsesVariousArt is not true: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber()); } } @@ -625,6 +627,11 @@ public class VerifyCardDataTest { return; } + // special check: kicker ability must be in rules + if (card.getAbilities().containsClass(MultikickerAbility.class) && !card.getRules().stream().anyMatch(rule -> rule.contains("Multikicker"))) { + fail(card, "abilities", "card have Multikicker ability, but missing it in rules text"); + } + // spells have only 1 abilities if (card.isSorcery() || card.isInstant()) { return; diff --git a/Mage/src/main/java/mage/abilities/effects/common/DrawCardSourceControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawCardSourceControllerEffect.java index b2e79fcd0e..ce8822a9d1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawCardSourceControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawCardSourceControllerEffect.java @@ -3,6 +3,7 @@ package mage.abilities.effects.common; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.MultikickerCount; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; @@ -51,7 +52,7 @@ public class DrawCardSourceControllerEffect extends OneShotEffect { private void setText() { StringBuilder sb = new StringBuilder(); boolean oneCard = (amount instanceof StaticValue && amount.calculate(null, null, this) == 1) - || amount instanceof PermanentsOnBattlefieldCount || amount.toString().equals("1"); + || amount instanceof PermanentsOnBattlefieldCount || amount.toString().equals("1") || amount.toString().equals("a"); sb.append("draw ").append(oneCard ? "a" : CardUtil.numberToText(amount.toString())).append(" card"); if (!oneCard) { sb.append('s'); From 9ba6a7ec5cb843ab9cbd55b75db2ebccae11fef9 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 12 Nov 2018 01:17:42 +0400 Subject: [PATCH 114/167] * Added new set Game Night (GNT) with 63 cards (5 not implemented yet); --- Mage.Sets/src/mage/sets/GameNight.java | 92 ++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/GameNight.java diff --git a/Mage.Sets/src/mage/sets/GameNight.java b/Mage.Sets/src/mage/sets/GameNight.java new file mode 100644 index 0000000000..076c056be1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/GameNight.java @@ -0,0 +1,92 @@ + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author JayDi85 + */ +public final class GameNight extends ExpansionSet { + + private static final GameNight instance = new GameNight(); + + public static GameNight getInstance() { + return instance; + } + + private GameNight() { + super("Game Night", "GNT", ExpansionSet.buildDate(2018, 11, 16), SetType.SUPPLEMENTAL); + this.hasBasicLands = true; + + cards.add(new SetCardInfo("Advanced Stitchwing", 18, Rarity.UNCOMMON, mage.cards.a.AdvancedStitchwing.class)); + cards.add(new SetCardInfo("Aerial Responder", 6, Rarity.UNCOMMON, mage.cards.a.AerialResponder.class)); + cards.add(new SetCardInfo("Air Elemental", 19, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); + cards.add(new SetCardInfo("Always Watching", 7, Rarity.RARE, mage.cards.a.AlwaysWatching.class)); + // TODO: cards.add(new SetCardInfo("Avatar of Growth", 5, Rarity.MYTHIC, mage.cards.a.AvatarOfGrowth.class)); + cards.add(new SetCardInfo("Benalish Marshal", 8, Rarity.RARE, mage.cards.b.BenalishMarshal.class)); + cards.add(new SetCardInfo("Bombard", 37, Rarity.COMMON, mage.cards.b.Bombard.class)); + cards.add(new SetCardInfo("Bone Splinters", 27, Rarity.COMMON, mage.cards.b.BoneSplinters.class)); + cards.add(new SetCardInfo("Bright Reprisal", 9, Rarity.UNCOMMON, mage.cards.b.BrightReprisal.class)); + cards.add(new SetCardInfo("Call the Cavalry", 10, Rarity.COMMON, mage.cards.c.CallTheCavalry.class)); + cards.add(new SetCardInfo("Captivating Crew", 38, Rarity.RARE, mage.cards.c.CaptivatingCrew.class)); + cards.add(new SetCardInfo("Claustrophobia", 20, Rarity.COMMON, mage.cards.c.Claustrophobia.class)); + cards.add(new SetCardInfo("Cruel Revival", 28, Rarity.UNCOMMON, mage.cards.c.CruelRevival.class)); + cards.add(new SetCardInfo("Dragon Fodder", 39, Rarity.COMMON, mage.cards.d.DragonFodder.class)); + cards.add(new SetCardInfo("Eager Construct", 51, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); + cards.add(new SetCardInfo("Everdawn Champion", 11, Rarity.UNCOMMON, mage.cards.e.EverdawnChampion.class)); + cards.add(new SetCardInfo("Fan Bearer", 12, Rarity.COMMON, mage.cards.f.FanBearer.class)); + cards.add(new SetCardInfo("Favorable Winds", 21, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); + cards.add(new SetCardInfo("Filigree Familiar", 52, Rarity.UNCOMMON, mage.cards.f.FiligreeFamiliar.class)); + cards.add(new SetCardInfo("Fleshbag Marauder", 29, Rarity.UNCOMMON, mage.cards.f.FleshbagMarauder.class)); + cards.add(new SetCardInfo("Forest", 67, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 68, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ghalta, Primal Hunger", 44, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class)); + // TODO: cards.add(new SetCardInfo("Goblin Goliath", 4, Rarity.MYTHIC, mage.cards.g.GoblinGoliath.class)); + cards.add(new SetCardInfo("Gruesome Fate", 30, Rarity.COMMON, mage.cards.g.GruesomeFate.class)); + cards.add(new SetCardInfo("Howling Golem", 53, Rarity.UNCOMMON, mage.cards.h.HowlingGolem.class)); + cards.add(new SetCardInfo("Hydrolash", 22, Rarity.UNCOMMON, mage.cards.h.Hydrolash.class)); + cards.add(new SetCardInfo("Inspired Charge", 13, Rarity.COMMON, mage.cards.i.InspiredCharge.class)); + // TODO: cards.add(new SetCardInfo("Inspired Sphinx", 2, Rarity.MYTHIC, mage.cards.i.InspiredSphinx.class)); + cards.add(new SetCardInfo("Inspiring Captain", 14, Rarity.COMMON, mage.cards.i.InspiringCaptain.class)); + cards.add(new SetCardInfo("Island", 61, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 62, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jungle Delver", 45, Rarity.COMMON, mage.cards.j.JungleDelver.class)); + cards.add(new SetCardInfo("Languish", 31, Rarity.RARE, mage.cards.l.Languish.class)); + cards.add(new SetCardInfo("Liliana's Mastery", 32, Rarity.RARE, mage.cards.l.LilianasMastery.class)); + cards.add(new SetCardInfo("Llanowar Elves", 46, Rarity.COMMON, mage.cards.l.LlanowarElves.class)); + cards.add(new SetCardInfo("Lord of the Accursed", 33, Rarity.UNCOMMON, mage.cards.l.LordOfTheAccursed.class)); + cards.add(new SetCardInfo("Manalith", 54, Rarity.COMMON, mage.cards.m.Manalith.class)); + cards.add(new SetCardInfo("Mesa Unicorn", 15, Rarity.COMMON, mage.cards.m.MesaUnicorn.class)); + // TODO: cards.add(new SetCardInfo("Militant Angel", 1, Rarity.MYTHIC, mage.cards.m.MilitantAngel.class)); + cards.add(new SetCardInfo("Mountain", 65, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 66, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Nissa's Revelation", 47, Rarity.RARE, mage.cards.n.NissasRevelation.class)); + cards.add(new SetCardInfo("Overcome", 48, Rarity.UNCOMMON, mage.cards.o.Overcome.class)); + cards.add(new SetCardInfo("Pilgrim's Eye", 55, Rarity.UNCOMMON, mage.cards.p.PilgrimsEye.class)); + cards.add(new SetCardInfo("Plains", 59, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 60, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Reckless Scholar", 23, Rarity.UNCOMMON, mage.cards.r.RecklessScholar.class)); + cards.add(new SetCardInfo("Rhonas's Monument", 56, Rarity.UNCOMMON, mage.cards.r.RhonassMonument.class)); + cards.add(new SetCardInfo("Rolling Thunder", 40, Rarity.UNCOMMON, mage.cards.r.RollingThunder.class)); + // TODO: cards.add(new SetCardInfo("Rot Hulk", 3, Rarity.MYTHIC, mage.cards.r.RotHulk.class)); + cards.add(new SetCardInfo("Seek the Wilds", 49, Rarity.COMMON, mage.cards.s.SeekTheWilds.class)); + cards.add(new SetCardInfo("Seismic Elemental", 41, Rarity.UNCOMMON, mage.cards.s.SeismicElemental.class)); + cards.add(new SetCardInfo("Serra Angel", 16, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class)); + cards.add(new SetCardInfo("Siege-Gang Commander", 42, Rarity.RARE, mage.cards.s.SiegeGangCommander.class)); + cards.add(new SetCardInfo("Snare Thopter", 57, Rarity.UNCOMMON, mage.cards.s.SnareThopter.class)); + cards.add(new SetCardInfo("Soulblade Djinn", 24, Rarity.RARE, mage.cards.s.SoulbladeDjinn.class)); + cards.add(new SetCardInfo("Subjugator Angel", 17, Rarity.UNCOMMON, mage.cards.s.SubjugatorAngel.class)); + cards.add(new SetCardInfo("Swamp", 63, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 64, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Tattered Mummy", 34, Rarity.COMMON, mage.cards.t.TatteredMummy.class)); + cards.add(new SetCardInfo("Thallid Soothsayer", 35, Rarity.UNCOMMON, mage.cards.t.ThallidSoothsayer.class)); + cards.add(new SetCardInfo("Thrashing Brontodon", 50, Rarity.UNCOMMON, mage.cards.t.ThrashingBrontodon.class)); + cards.add(new SetCardInfo("Tormenting Voice", 43, Rarity.COMMON, mage.cards.t.TormentingVoice.class)); + cards.add(new SetCardInfo("Welder Automaton", 58, Rarity.COMMON, mage.cards.w.WelderAutomaton.class)); + cards.add(new SetCardInfo("Whirler Rogue", 25, Rarity.UNCOMMON, mage.cards.w.WhirlerRogue.class)); + cards.add(new SetCardInfo("Zahid, Djinn of the Lamp", 26, Rarity.RARE, mage.cards.z.ZahidDjinnOfTheLamp.class)); + cards.add(new SetCardInfo("Zulaport Cutthroat", 36, Rarity.UNCOMMON, mage.cards.z.ZulaportCutthroat.class)); + } +} From 4b87af1c743b36e6461d53fd509b4ea650a7823b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 12 Nov 2018 01:29:13 +0400 Subject: [PATCH 115/167] * Added new set Ultimate Masters (UMA) with 41 cards (other cards will be added later); --- Mage.Sets/src/mage/sets/UltimateMasters.java | 72 ++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/UltimateMasters.java diff --git a/Mage.Sets/src/mage/sets/UltimateMasters.java b/Mage.Sets/src/mage/sets/UltimateMasters.java new file mode 100644 index 0000000000..a97affe33b --- /dev/null +++ b/Mage.Sets/src/mage/sets/UltimateMasters.java @@ -0,0 +1,72 @@ + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author JayDi85 + */ +public final class UltimateMasters extends ExpansionSet { + + private static final UltimateMasters instance = new UltimateMasters(); + + public static UltimateMasters getInstance() { + return instance; + } + + private UltimateMasters() { + super("Ultimate Masters", "UMA", ExpansionSet.buildDate(2018, 12, 7), SetType.SUPPLEMENTAL); + this.blockName = "Reprint"; + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 8; + + cards.add(new SetCardInfo("Ancient Tomb", 236, Rarity.RARE, mage.cards.a.AncientTomb.class)); + cards.add(new SetCardInfo("Balefire Dragon", 124, Rarity.MYTHIC, mage.cards.b.BalefireDragon.class)); + cards.add(new SetCardInfo("Bitterblossom", 85, Rarity.MYTHIC, mage.cards.b.Bitterblossom.class)); + cards.add(new SetCardInfo("Cavern of Souls", 237, Rarity.MYTHIC, mage.cards.c.CavernOfSouls.class)); + cards.add(new SetCardInfo("Celestial Colonnade", 238, Rarity.RARE, mage.cards.c.CelestialColonnade.class)); + cards.add(new SetCardInfo("Creeping Tar Pit", 239, Rarity.RARE, mage.cards.c.CreepingTarPit.class)); + cards.add(new SetCardInfo("Dark Depths", 241, Rarity.MYTHIC, mage.cards.d.DarkDepths.class)); + cards.add(new SetCardInfo("Demonic Tutor", 93, Rarity.RARE, mage.cards.d.DemonicTutor.class)); + cards.add(new SetCardInfo("Emrakul, the Aeons Torn", 4, Rarity.MYTHIC, mage.cards.e.EmrakulTheAeonsTorn.class)); + cards.add(new SetCardInfo("Engineered Explosives", 227, Rarity.RARE, mage.cards.e.EngineeredExplosives.class)); + cards.add(new SetCardInfo("Entomb", 94, Rarity.RARE, mage.cards.e.Entomb.class)); + cards.add(new SetCardInfo("Eternal Witness", 163, Rarity.UNCOMMON, mage.cards.e.EternalWitness.class)); + cards.add(new SetCardInfo("Fulminator Mage", 215, Rarity.RARE, mage.cards.f.FulminatorMage.class)); + cards.add(new SetCardInfo("Gaddock Teeg", 199, Rarity.RARE, mage.cards.g.GaddockTeeg.class)); + cards.add(new SetCardInfo("Goryo's Vengeance", 99, Rarity.RARE, mage.cards.g.GoryosVengeance.class)); + cards.add(new SetCardInfo("Karakas", 244, Rarity.MYTHIC, mage.cards.k.Karakas.class)); + cards.add(new SetCardInfo("Karn Liberated", 5, Rarity.MYTHIC, mage.cards.k.KarnLiberated.class)); + cards.add(new SetCardInfo("Kitchen Finks", 216, Rarity.UNCOMMON, mage.cards.k.KitchenFinks.class)); + cards.add(new SetCardInfo("Kozilek, Butcher of Truth", 6, Rarity.MYTHIC, mage.cards.k.KozilekButcherOfTruth.class)); + cards.add(new SetCardInfo("Lavaclaw Reaches", 245, Rarity.RARE, mage.cards.l.LavaclawReaches.class)); + cards.add(new SetCardInfo("Leovold, Emissary of Trest", 202, Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); + cards.add(new SetCardInfo("Life from the Loam", 172, Rarity.RARE, mage.cards.l.LifeFromTheLoam.class)); + cards.add(new SetCardInfo("Liliana of the Veil", 104, Rarity.MYTHIC, mage.cards.l.LilianaOfTheVeil.class)); + cards.add(new SetCardInfo("Lord of Extinction", 203, Rarity.MYTHIC, mage.cards.l.LordOfExtinction.class)); + cards.add(new SetCardInfo("Maelstrom Pulse", 204, Rarity.RARE, mage.cards.m.MaelstromPulse.class)); + cards.add(new SetCardInfo("Mana Vault", 229, Rarity.MYTHIC, mage.cards.m.ManaVault.class)); + cards.add(new SetCardInfo("Mikaeus, the Unhallowed", 106, Rarity.MYTHIC, mage.cards.m.MikaeusTheUnhallowed.class)); + cards.add(new SetCardInfo("Noble Hierarch", 174, Rarity.RARE, mage.cards.n.NobleHierarch.class)); + cards.add(new SetCardInfo("Platinum Emperion", 233, Rarity.MYTHIC, mage.cards.p.PlatinumEmperion.class)); + cards.add(new SetCardInfo("Raging Ravine", 249, Rarity.RARE, mage.cards.r.RagingRavine.class)); + cards.add(new SetCardInfo("Reanimate", 110, Rarity.RARE, mage.cards.r.Reanimate.class)); + cards.add(new SetCardInfo("Sigarda, Host of Herons", 206, Rarity.MYTHIC, mage.cards.s.SigardaHostOfHerons.class)); + cards.add(new SetCardInfo("Snapcaster Mage", 71, Rarity.MYTHIC, mage.cards.s.SnapcasterMage.class)); + cards.add(new SetCardInfo("Stirring Wildwood", 251, Rarity.RARE, mage.cards.s.StirringWildwood.class)); + cards.add(new SetCardInfo("Tarmogoyf", 187, Rarity.MYTHIC, mage.cards.t.Tarmogoyf.class)); + cards.add(new SetCardInfo("Tasigur, the Golden Fang", 117, Rarity.RARE, mage.cards.t.TasigurTheGoldenFang.class)); + cards.add(new SetCardInfo("Temporal Manipulation", 77, Rarity.MYTHIC, mage.cards.t.TemporalManipulation.class)); + cards.add(new SetCardInfo("Through the Breach", 152, Rarity.RARE, mage.cards.t.ThroughTheBreach.class)); + cards.add(new SetCardInfo("Ulamog, the Infinite Gyre", 7, Rarity.MYTHIC, mage.cards.u.UlamogTheInfiniteGyre.class)); + cards.add(new SetCardInfo("Urborg, Tomb of Yawgmoth", 254, Rarity.RARE, mage.cards.u.UrborgTombOfYawgmoth.class)); + cards.add(new SetCardInfo("Vengevine", 189, Rarity.MYTHIC, mage.cards.v.Vengevine.class)); + } +} From 2452e07a0fa555a580086068682c250b8defbf31 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 12 Nov 2018 01:36:14 +0400 Subject: [PATCH 116/167] * Added new set Ultimate Box Topper Promos (PUMA) with 40 cards; --- .../mage/sets/UltimateBoxTopperPromos.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java diff --git a/Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java b/Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java new file mode 100644 index 0000000000..26eb20d571 --- /dev/null +++ b/Mage.Sets/src/mage/sets/UltimateBoxTopperPromos.java @@ -0,0 +1,65 @@ + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author JayDi85 + */ +public final class UltimateBoxTopperPromos extends ExpansionSet { + + private static final UltimateBoxTopperPromos instance = new UltimateBoxTopperPromos(); + + public static UltimateBoxTopperPromos getInstance() { + return instance; + } + + private UltimateBoxTopperPromos() { + super("Ultimate Box Topper Promos", "PUMA", ExpansionSet.buildDate(2018, 12, 7), SetType.PROMOTIONAL); + this.hasBasicLands = false; + this.hasBoosters = false; + + cards.add(new SetCardInfo("Ancient Tomb", "U31", Rarity.MYTHIC, mage.cards.a.AncientTomb.class)); + cards.add(new SetCardInfo("Balefire Dragon", "U14", Rarity.MYTHIC, mage.cards.b.BalefireDragon.class)); + cards.add(new SetCardInfo("Bitterblossom", "U7", Rarity.MYTHIC, mage.cards.b.Bitterblossom.class)); + cards.add(new SetCardInfo("Cavern of Souls", "U32", Rarity.MYTHIC, mage.cards.c.CavernOfSouls.class)); + cards.add(new SetCardInfo("Celestial Colonnade", "U33", Rarity.MYTHIC, mage.cards.c.CelestialColonnade.class)); + cards.add(new SetCardInfo("Creeping Tar Pit", "U34", Rarity.MYTHIC, mage.cards.c.CreepingTarPit.class)); + cards.add(new SetCardInfo("Dark Depths", "U35", Rarity.MYTHIC, mage.cards.d.DarkDepths.class)); + cards.add(new SetCardInfo("Demonic Tutor", "U8", Rarity.MYTHIC, mage.cards.d.DemonicTutor.class)); + cards.add(new SetCardInfo("Emrakul, the Aeons Torn", "U1", Rarity.MYTHIC, mage.cards.e.EmrakulTheAeonsTorn.class)); + cards.add(new SetCardInfo("Engineered Explosives", "U28", Rarity.MYTHIC, mage.cards.e.EngineeredExplosives.class)); + cards.add(new SetCardInfo("Eternal Witness", "U16", Rarity.MYTHIC, mage.cards.e.EternalWitness.class)); + cards.add(new SetCardInfo("Fulminator Mage", "U26", Rarity.MYTHIC, mage.cards.f.FulminatorMage.class)); + cards.add(new SetCardInfo("Gaddock Teeg", "U21", Rarity.MYTHIC, mage.cards.g.GaddockTeeg.class)); + cards.add(new SetCardInfo("Goryo's Vengeance", "U9", Rarity.MYTHIC, mage.cards.g.GoryosVengeance.class)); + cards.add(new SetCardInfo("Karakas", "U36", Rarity.MYTHIC, mage.cards.k.Karakas.class)); + cards.add(new SetCardInfo("Karn Liberated", "U02", Rarity.MYTHIC, mage.cards.k.KarnLiberated.class)); + cards.add(new SetCardInfo("Kitchen Finks", "U27", Rarity.MYTHIC, mage.cards.k.KitchenFinks.class)); + cards.add(new SetCardInfo("Kozilek, Butcher of Truth", "U03", Rarity.MYTHIC, mage.cards.k.KozilekButcherOfTruth.class)); + cards.add(new SetCardInfo("Lavaclaw Reaches", "U37", Rarity.MYTHIC, mage.cards.l.LavaclawReaches.class)); + cards.add(new SetCardInfo("Leovold, Emissary of Trest", "U22", Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); + cards.add(new SetCardInfo("Life from the Loam", "U17", Rarity.MYTHIC, mage.cards.l.LifeFromTheLoam.class)); + cards.add(new SetCardInfo("Liliana of the Veil", "U10", Rarity.MYTHIC, mage.cards.l.LilianaOfTheVeil.class)); + cards.add(new SetCardInfo("Lord of Extinction", "U23", Rarity.MYTHIC, mage.cards.l.LordOfExtinction.class)); + cards.add(new SetCardInfo("Maelstrom Pulse", "U24", Rarity.MYTHIC, mage.cards.m.MaelstromPulse.class)); + cards.add(new SetCardInfo("Mana Vault", "U29", Rarity.MYTHIC, mage.cards.m.ManaVault.class)); + cards.add(new SetCardInfo("Mikaeus, the Unhallowed", "U11", Rarity.MYTHIC, mage.cards.m.MikaeusTheUnhallowed.class)); + cards.add(new SetCardInfo("Noble Hierarch", "U18", Rarity.MYTHIC, mage.cards.n.NobleHierarch.class)); + cards.add(new SetCardInfo("Platinum Emperion", "U30", Rarity.MYTHIC, mage.cards.p.PlatinumEmperion.class)); + cards.add(new SetCardInfo("Raging Ravine", "U38", Rarity.MYTHIC, mage.cards.r.RagingRavine.class)); + cards.add(new SetCardInfo("Reanimate", "U12", Rarity.MYTHIC, mage.cards.r.Reanimate.class)); + cards.add(new SetCardInfo("Sigarda, Host of Herons", "U25", Rarity.MYTHIC, mage.cards.s.SigardaHostOfHerons.class)); + cards.add(new SetCardInfo("Snapcaster Mage", "U5", Rarity.MYTHIC, mage.cards.s.SnapcasterMage.class)); + cards.add(new SetCardInfo("Stirring Wildwood", "U39", Rarity.MYTHIC, mage.cards.s.StirringWildwood.class)); + cards.add(new SetCardInfo("Tarmogoyf", "U19", Rarity.MYTHIC, mage.cards.t.Tarmogoyf.class)); + cards.add(new SetCardInfo("Tasigur, the Golden Fang", "U13", Rarity.MYTHIC, mage.cards.t.TasigurTheGoldenFang.class)); + cards.add(new SetCardInfo("Temporal Manipulation", "U6", Rarity.MYTHIC, mage.cards.t.TemporalManipulation.class)); + cards.add(new SetCardInfo("Through the Breach", "U15", Rarity.MYTHIC, mage.cards.t.ThroughTheBreach.class)); + cards.add(new SetCardInfo("Ulamog, the Infinite Gyre", "U4", Rarity.MYTHIC, mage.cards.u.UlamogTheInfiniteGyre.class)); + cards.add(new SetCardInfo("Urborg, Tomb of Yawgmoth", "U40", Rarity.MYTHIC, mage.cards.u.UrborgTombOfYawgmoth.class)); + cards.add(new SetCardInfo("Vengevine", "U20", Rarity.MYTHIC, mage.cards.v.Vengevine.class)); + } +} From b298a621fbe421da1cfbd6fa4201a187e47cdd44 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 12 Nov 2018 01:39:31 +0400 Subject: [PATCH 117/167] Added scryfall download for new set: GNT, UMA, PUMA --- .../org/mage/plugins/card/dl/sources/ScryfallImageSource.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 4cac40e221..463005b8d5 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -231,6 +231,9 @@ public enum ScryfallImageSource implements CardImageSource { supportedSets.add("GS1"); supportedSets.add("GRN"); supportedSets.add("GK1"); + supportedSets.add("GNT"); + supportedSets.add("UMA"); + supportedSets.add("PUMA"); // supportedSets.add("EURO"); supportedSets.add("GPX"); From 0b089895a7be18f61b0a441d2aee08986c5c1733 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 12 Nov 2018 02:23:11 +0400 Subject: [PATCH 118/167] Fixed scryfall images download for PUMA set; --- .../card/dl/sources/ScryfallImageSource.java | 21 +++++++++++++------ Mage/src/main/java/mage/util/CardUtil.java | 13 ++++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 463005b8d5..fa6dc551c3 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -250,7 +250,9 @@ public enum ScryfallImageSource implements CardImageSource { String localizedCode = languageAliases.getOrDefault(preferredLanguage, defaultCode); // loc example: https://api.scryfall.com/cards/xln/121/ru?format=image - // TODO: do not use API at all? It's can help with scryfall request limits (1 request instead 2) + // WARNING, some cards haven't direct images and uses random GUID: + // As example: Raging Ravine - https://scryfall.com/card/uma/249/raging-ravine + // https://img.scryfall.com/cards/large/front/5/4/54f41726-e0bb-4154-a2db-4b68b50f5032.jpg String baseUrl = null; String alternativeUrl = null; @@ -272,12 +274,19 @@ public enum ScryfallImageSource implements CardImageSource { } } - // special card number like "103a" already compatible + // special card number like "103a" and "U123" already compatible if (baseUrl == null && card.isCollectorIdWithStr()) { - baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/" - + card.getCollectorId() + ".jpg"; - alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/" - + card.getCollectorId() + ".jpg"; + // WARNING, after 2018 it's not compatible and some new sets have GUID files instead card numbers + // TODO: replace card number links to API calls (need test with lands, alternative images and double faces), replace not working images by direct links + if (card.getCollectorId().startsWith("U")) { + // fix for Ultimate Box Topper (PUMA) -- need to use API + // ignored and go to API call at the end + } else { + baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/" + + card.getCollectorId() + ".jpg"; + alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/" + + card.getCollectorId() + ".jpg"; + } } // double faced cards do not supports by API (need direct link for img) diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index ac9a02f558..53da40ceef 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -362,7 +362,7 @@ public final class CardUtil { /** * Parse card number as int (support base [123] and alternative numbers - * [123b]). + * [123b], [U123]). * * @param cardNumber origin card number * @return int @@ -373,10 +373,15 @@ public final class CardUtil { throw new IllegalArgumentException("Card number is empty."); } - if (Character.isDigit(cardNumber.charAt(cardNumber.length() - 1))) { - return Integer.parseInt(cardNumber); - } else { + if (!Character.isDigit(cardNumber.charAt(0))) { + // U123 + return Integer.parseInt(cardNumber.substring(1, cardNumber.length())); + } else if (!Character.isDigit(cardNumber.charAt(cardNumber.length() - 1))) { + // 123b return Integer.parseInt(cardNumber.substring(0, cardNumber.length() - 1)); + } else { + // 123 + return Integer.parseInt(cardNumber); } } From a0e4791ad63f08ca70cfd0d848c4c4bd085df83c Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 12 Nov 2018 04:17:04 +0400 Subject: [PATCH 119/167] [GNT] implemented Avatar of Growth --- .../src/mage/cards/a/AvatarOfGrowth.java | 93 +++++++++++++++++++ Mage.Sets/src/mage/sets/GameNight.java | 2 +- ...CostReductionSourceForOpponentsEffect.java | 52 +++++++++++ .../abilities/keyword/UndauntedAbility.java | 53 +---------- 4 files changed, 149 insertions(+), 51 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AvatarOfGrowth.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceForOpponentsEffect.java diff --git a/Mage.Sets/src/mage/cards/a/AvatarOfGrowth.java b/Mage.Sets/src/mage/cards/a/AvatarOfGrowth.java new file mode 100644 index 0000000000..41cb467003 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AvatarOfGrowth.java @@ -0,0 +1,93 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.cost.SpellCostReductionSourceForOpponentsEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class AvatarOfGrowth extends CardImpl { + + public AvatarOfGrowth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.AVATAR); + + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // This spell costs {1} less to cast for each opponent you have. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceForOpponentsEffect("This spell costs {1} less to cast for each opponent you have"))); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // When Avatar of Growth enters the battlefield, each player searches their library for up to two basic land cards, puts them onto the battlefield, then shuffles their library. + this.addAbility(new EntersBattlefieldTriggeredAbility(new AvatarOfGrowthSearchEffect())); + } + + public AvatarOfGrowth(final AvatarOfGrowth card) { + super(card); + } + + @Override + public AvatarOfGrowth copy() { + return new AvatarOfGrowth(this); + } +} + +class AvatarOfGrowthSearchEffect extends OneShotEffect { + + public AvatarOfGrowthSearchEffect() { + super(Outcome.Detriment); + this.staticText = "each player searches their library for up to two basic land cards, puts them onto the battlefield, then shuffles their libarary"; + } + + public AvatarOfGrowthSearchEffect(final AvatarOfGrowthSearchEffect effect) { + super(effect); + } + + @Override + public AvatarOfGrowthSearchEffect copy() { + return new AvatarOfGrowthSearchEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); + if (player.searchLibrary(target, game)) { + if (!target.getTargets().isEmpty()) { + player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); + } + } + player.shuffleLibrary(source, game); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/GameNight.java b/Mage.Sets/src/mage/sets/GameNight.java index 076c056be1..3669229792 100644 --- a/Mage.Sets/src/mage/sets/GameNight.java +++ b/Mage.Sets/src/mage/sets/GameNight.java @@ -24,7 +24,7 @@ public final class GameNight extends ExpansionSet { cards.add(new SetCardInfo("Aerial Responder", 6, Rarity.UNCOMMON, mage.cards.a.AerialResponder.class)); cards.add(new SetCardInfo("Air Elemental", 19, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); cards.add(new SetCardInfo("Always Watching", 7, Rarity.RARE, mage.cards.a.AlwaysWatching.class)); - // TODO: cards.add(new SetCardInfo("Avatar of Growth", 5, Rarity.MYTHIC, mage.cards.a.AvatarOfGrowth.class)); + cards.add(new SetCardInfo("Avatar of Growth", 5, Rarity.MYTHIC, mage.cards.a.AvatarOfGrowth.class)); cards.add(new SetCardInfo("Benalish Marshal", 8, Rarity.RARE, mage.cards.b.BenalishMarshal.class)); cards.add(new SetCardInfo("Bombard", 37, Rarity.COMMON, mage.cards.b.Bombard.class)); cards.add(new SetCardInfo("Bone Splinters", 27, Rarity.COMMON, mage.cards.b.BoneSplinters.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceForOpponentsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceForOpponentsEffect.java new file mode 100644 index 0000000000..4391755fa3 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellCostReductionSourceForOpponentsEffect.java @@ -0,0 +1,52 @@ +package mage.abilities.effects.common.cost; + +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; + +public class SpellCostReductionSourceForOpponentsEffect extends CostModificationEffectImpl { + + public SpellCostReductionSourceForOpponentsEffect() { + this("undaunted (This spell costs {1} less to cast for each opponent.)"); + } + + public SpellCostReductionSourceForOpponentsEffect(String newStaticText) { + super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = newStaticText; + } + + public SpellCostReductionSourceForOpponentsEffect(final SpellCostReductionSourceForOpponentsEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + SpellAbility spellAbility = (SpellAbility) abilityToModify; + Mana mana = spellAbility.getManaCostsToPay().getMana(); + if (mana.getGeneric() > 0) { + int count = game.getOpponents(source.getControllerId()).size(); + int newCount = mana.getGeneric() - count; + if (newCount < 0) { + newCount = 0; + } + mana.setGeneric(newCount); + spellAbility.getManaCostsToPay().load(mana.toString()); + return true; + } + return false; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + return abilityToModify instanceof SpellAbility && abilityToModify.getSourceId().equals(source.getSourceId()); + } + + @Override + public SpellCostReductionSourceForOpponentsEffect copy() { + return new SpellCostReductionSourceForOpponentsEffect(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/UndauntedAbility.java b/Mage/src/main/java/mage/abilities/keyword/UndauntedAbility.java index 857d47133b..52061608d3 100644 --- a/Mage/src/main/java/mage/abilities/keyword/UndauntedAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/UndauntedAbility.java @@ -5,25 +5,17 @@ */ package mage.abilities.keyword; -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.cost.CostModificationEffectImpl; -import mage.constants.CostModificationType; -import mage.constants.Duration; -import mage.constants.Outcome; +import mage.abilities.effects.common.cost.SpellCostReductionSourceForOpponentsEffect; import mage.constants.Zone; -import mage.game.Game; /** - * * @author LevelX2 */ public class UndauntedAbility extends SimpleStaticAbility { public UndauntedAbility() { - super(Zone.ALL, new UndauntedEffect()); + super(Zone.ALL, new SpellCostReductionSourceForOpponentsEffect("undaunted (This spell costs {1} less to cast for each opponent.)")); setRuleAtTheTop(true); } @@ -36,43 +28,4 @@ public class UndauntedAbility extends SimpleStaticAbility { return new UndauntedAbility(this); } -} - -class UndauntedEffect extends CostModificationEffectImpl { - - public UndauntedEffect() { - super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST); - staticText = "undaunted (This spell costs {1} less to cast for each opponent.)"; - } - - public UndauntedEffect(final UndauntedEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source, Ability abilityToModify) { - SpellAbility spellAbility = (SpellAbility) abilityToModify; - Mana mana = spellAbility.getManaCostsToPay().getMana(); - if (mana.getGeneric() > 0) { - int count = game.getOpponents(source.getControllerId()).size(); - int newCount = mana.getGeneric() - count; - if (newCount < 0) { - newCount = 0; - } - mana.setGeneric(newCount); - spellAbility.getManaCostsToPay().load(mana.toString()); - return true; - } - return false; - } - - @Override - public boolean applies(Ability abilityToModify, Ability source, Game game) { - return abilityToModify instanceof SpellAbility && abilityToModify.getSourceId().equals(source.getSourceId()); - } - - @Override - public UndauntedEffect copy() { - return new UndauntedEffect(this); - } -} +} \ No newline at end of file From 209bccef0cd78013012648ac724ea4a770bb1335 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 12 Nov 2018 22:31:42 +0400 Subject: [PATCH 120/167] [GNT] implemented Inspired Sphinx --- .../src/mage/cards/i/InspiredSphinx.java | 60 +++++++++++++++++++ Mage.Sets/src/mage/sets/GameNight.java | 2 +- .../dynamicvalue/common/OpponentsCount.java | 32 ++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/i/InspiredSphinx.java create mode 100644 Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsCount.java diff --git a/Mage.Sets/src/mage/cards/i/InspiredSphinx.java b/Mage.Sets/src/mage/cards/i/InspiredSphinx.java new file mode 100644 index 0000000000..2fe8e4e7a7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InspiredSphinx.java @@ -0,0 +1,60 @@ +package mage.cards.i; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.OpponentsCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.permanent.token.ThopterColorlessToken; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class InspiredSphinx extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("Wizard"); + + static { + filter.add(new SubtypePredicate(SubType.WIZARD)); + } + + public InspiredSphinx(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); + this.subtype.add(SubType.SPHINX); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Inspired Sphinx enters the battlefield, draw cards equal to the number of opponents you have. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new DrawCardSourceControllerEffect(new OpponentsCount()).setText("draw cards equal to the number of opponents you have") + )); + + // {3}{U}: Create a colorless 1/1 Thopter artifact creature token with flying. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new ThopterColorlessToken()), new ManaCostsImpl<>("{3}{U}"))); + } + + public InspiredSphinx(final InspiredSphinx card) { + super(card); + } + + @Override + public InspiredSphinx copy() { + return new InspiredSphinx(this); + } +} diff --git a/Mage.Sets/src/mage/sets/GameNight.java b/Mage.Sets/src/mage/sets/GameNight.java index 3669229792..1a69efd0e5 100644 --- a/Mage.Sets/src/mage/sets/GameNight.java +++ b/Mage.Sets/src/mage/sets/GameNight.java @@ -48,7 +48,7 @@ public final class GameNight extends ExpansionSet { cards.add(new SetCardInfo("Howling Golem", 53, Rarity.UNCOMMON, mage.cards.h.HowlingGolem.class)); cards.add(new SetCardInfo("Hydrolash", 22, Rarity.UNCOMMON, mage.cards.h.Hydrolash.class)); cards.add(new SetCardInfo("Inspired Charge", 13, Rarity.COMMON, mage.cards.i.InspiredCharge.class)); - // TODO: cards.add(new SetCardInfo("Inspired Sphinx", 2, Rarity.MYTHIC, mage.cards.i.InspiredSphinx.class)); + cards.add(new SetCardInfo("Inspired Sphinx", 2, Rarity.MYTHIC, mage.cards.i.InspiredSphinx.class)); cards.add(new SetCardInfo("Inspiring Captain", 14, Rarity.COMMON, mage.cards.i.InspiringCaptain.class)); cards.add(new SetCardInfo("Island", 61, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 62, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsCount.java new file mode 100644 index 0000000000..2435bb53ad --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsCount.java @@ -0,0 +1,32 @@ +package mage.abilities.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.game.Game; + +/** + * @author JayDi85 + */ +public class OpponentsCount implements DynamicValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return game.getOpponents(sourceAbility.getControllerId()).size(); + } + + @Override + public OpponentsCount copy() { + return new OpponentsCount(); + } + + @Override + public String getMessage() { + return "number of opponents you have"; + } + + @Override + public String toString() { + return "1"; + } +} \ No newline at end of file From 9986c1d3651ffec4d3e2d08272a447f4d7fa10e8 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 13 Nov 2018 00:25:48 +0400 Subject: [PATCH 121/167] [GNT] implemented Militant Angel --- .../src/mage/cards/i/InspiredSphinx.java | 9 -- Mage.Sets/src/mage/cards/m/MilitantAngel.java | 49 ++++++++++ Mage.Sets/src/mage/sets/GameNight.java | 2 +- .../AttackedThisTurnOpponentsCount.java | 44 +++++++++ Mage/src/main/java/mage/game/GameImpl.java | 1 + .../PlayersAttackedThisTurnWatcher.java | 91 +++++++++++++++++++ 6 files changed, 186 insertions(+), 10 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/m/MilitantAngel.java create mode 100644 Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java create mode 100644 Mage/src/main/java/mage/watchers/common/PlayersAttackedThisTurnWatcher.java diff --git a/Mage.Sets/src/mage/cards/i/InspiredSphinx.java b/Mage.Sets/src/mage/cards/i/InspiredSphinx.java index 2fe8e4e7a7..f3e793d77e 100644 --- a/Mage.Sets/src/mage/cards/i/InspiredSphinx.java +++ b/Mage.Sets/src/mage/cards/i/InspiredSphinx.java @@ -7,15 +7,12 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.OpponentsCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.FilterSpell; -import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.permanent.token.ThopterColorlessToken; import java.util.UUID; @@ -25,12 +22,6 @@ import java.util.UUID; */ public final class InspiredSphinx extends CardImpl { - private static final FilterSpell filter = new FilterSpell("Wizard"); - - static { - filter.add(new SubtypePredicate(SubType.WIZARD)); - } - public InspiredSphinx(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); this.subtype.add(SubType.SPHINX); diff --git a/Mage.Sets/src/mage/cards/m/MilitantAngel.java b/Mage.Sets/src/mage/cards/m/MilitantAngel.java new file mode 100644 index 0000000000..790f1e62c1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MilitantAngel.java @@ -0,0 +1,49 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.AttackedThisTurnOpponentsCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.KnightToken; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class MilitantAngel extends CardImpl { + + public MilitantAngel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); + this.subtype.add(SubType.ANGEL); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // When Militant Angel enters the battlefield, create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn. + Effect effect = new CreateTokenEffect(new KnightToken(), new AttackedThisTurnOpponentsCount()); + effect.setText("create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn"); + this.addAbility(new EntersBattlefieldTriggeredAbility(effect)); + } + + public MilitantAngel(final MilitantAngel card) { + super(card); + } + + @Override + public MilitantAngel copy() { + return new MilitantAngel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/GameNight.java b/Mage.Sets/src/mage/sets/GameNight.java index 1a69efd0e5..cfb9b33749 100644 --- a/Mage.Sets/src/mage/sets/GameNight.java +++ b/Mage.Sets/src/mage/sets/GameNight.java @@ -59,7 +59,7 @@ public final class GameNight extends ExpansionSet { cards.add(new SetCardInfo("Lord of the Accursed", 33, Rarity.UNCOMMON, mage.cards.l.LordOfTheAccursed.class)); cards.add(new SetCardInfo("Manalith", 54, Rarity.COMMON, mage.cards.m.Manalith.class)); cards.add(new SetCardInfo("Mesa Unicorn", 15, Rarity.COMMON, mage.cards.m.MesaUnicorn.class)); - // TODO: cards.add(new SetCardInfo("Militant Angel", 1, Rarity.MYTHIC, mage.cards.m.MilitantAngel.class)); + cards.add(new SetCardInfo("Militant Angel", 1, Rarity.MYTHIC, mage.cards.m.MilitantAngel.class)); cards.add(new SetCardInfo("Mountain", 65, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 66, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nissa's Revelation", 47, Rarity.RARE, mage.cards.n.NissasRevelation.class)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java new file mode 100644 index 0000000000..69a12d8c92 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java @@ -0,0 +1,44 @@ + +package mage.abilities.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.game.Game; +import mage.watchers.common.PlayersAttackedThisTurnWatcher; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public class AttackedThisTurnOpponentsCount implements DynamicValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return this.calculate(game, sourceAbility.getControllerId()); + } + + public int calculate(Game game, UUID controllerId) { + PlayersAttackedThisTurnWatcher watcher = (PlayersAttackedThisTurnWatcher) game.getState().getWatchers().get(PlayersAttackedThisTurnWatcher.class.getSimpleName()); + if (watcher != null) { + return watcher.getAttackedOpponentsCount(controllerId); + } + return 0; + } + + @Override + public AttackedThisTurnOpponentsCount copy() { + return new AttackedThisTurnOpponentsCount(); + } + + @Override + public String toString() { + return "1"; + } + + @Override + public String getMessage() { + return "the number of opponents you attacked this turn"; + } +} diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index be845c2c26..c0fa488e20 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -1026,6 +1026,7 @@ public abstract class GameImpl implements Game, Serializable { watchers.add(new BlockedAttackerWatcher()); watchers.add(new DamageDoneWatcher()); watchers.add(new PlanarRollWatcher()); + watchers.add(new PlayersAttackedThisTurnWatcher()); //20100716 - 103.5 for (UUID playerId : state.getPlayerList(startingPlayerId)) { diff --git a/Mage/src/main/java/mage/watchers/common/PlayersAttackedThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/PlayersAttackedThisTurnWatcher.java new file mode 100644 index 0000000000..0099fb1267 --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/PlayersAttackedThisTurnWatcher.java @@ -0,0 +1,91 @@ +package mage.watchers.common; + +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.PlayerList; +import mage.watchers.Watcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @author JayDi85 + */ +public class PlayersAttackedThisTurnWatcher extends Watcher { + + // how many players or opponents each player attacked this turn + private final Map playersAttackedThisTurn = new HashMap<>(); + private final Map opponentsAttackedThisTurn = new HashMap<>(); + + public PlayersAttackedThisTurnWatcher() { + super(PlayersAttackedThisTurnWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public PlayersAttackedThisTurnWatcher(final PlayersAttackedThisTurnWatcher watcher) { + super(watcher); + + for (Map.Entry entry : watcher.playersAttackedThisTurn.entrySet()) { + this.playersAttackedThisTurn.put(entry.getKey(), entry.getValue()); + } + + for (Map.Entry entry : watcher.opponentsAttackedThisTurn.entrySet()) { + this.opponentsAttackedThisTurn.put(entry.getKey(), entry.getValue()); + } + } + + @Override + public PlayersAttackedThisTurnWatcher copy() { + return new PlayersAttackedThisTurnWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.BEGINNING_PHASE_PRE) { + playersAttackedThisTurn.clear(); + opponentsAttackedThisTurn.clear(); + } + + if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) { + + // players + PlayerList playersAttacked = playersAttackedThisTurn.get(event.getPlayerId()); + if (playersAttacked == null) { + playersAttacked = new PlayerList(); + } + UUID playerDefender = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); + if (playerDefender != null) { + playersAttacked.add(playerDefender); + } + playersAttackedThisTurn.put(event.getPlayerId(), playersAttacked); + + // opponents + PlayerList opponentsAttacked = opponentsAttackedThisTurn.get(event.getPlayerId()); + if (opponentsAttacked == null) { + opponentsAttacked = new PlayerList(); + } + UUID opponentDefender = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); + if (opponentDefender != null && game.getOpponents(event.getPlayerId()).contains(opponentDefender)) { + opponentsAttacked.add(opponentDefender); + } + opponentsAttackedThisTurn.put(event.getPlayerId(), opponentsAttacked); + } + } + + public int getAttackedPlayersCount(UUID playerID) { + PlayerList defendersList = playersAttackedThisTurn.getOrDefault(playerID, null); + if (defendersList != null) { + return defendersList.size(); + } + return 0; + } + + public int getAttackedOpponentsCount(UUID playerID) { + PlayerList defendersList = opponentsAttackedThisTurn.getOrDefault(playerID, null); + if (defendersList != null) { + return defendersList.size(); + } + return 0; + } +} From 2c89ec92d30113276a366ba94bc5d5f8ce27d5cb Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 13 Nov 2018 01:15:24 +0400 Subject: [PATCH 122/167] [GNT] implemented Rot Hulk --- Mage.Sets/src/mage/cards/r/RotHulk.java | 72 +++++++++++++++++++++++++ Mage.Sets/src/mage/sets/GameNight.java | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/r/RotHulk.java diff --git a/Mage.Sets/src/mage/cards/r/RotHulk.java b/Mage.Sets/src/mage/cards/r/RotHulk.java new file mode 100644 index 0000000000..152f27ddca --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RotHulk.java @@ -0,0 +1,72 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.OpponentsCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class RotHulk extends CardImpl { + + private static final FilterCard filterZombie = new FilterCard("Zombie cards from your graveyard"); + + static { + filterZombie.add(new SubtypePredicate(SubType.ZOMBIE)); + } + + private final UUID entersBattlefieldAbilityID; + + public RotHulk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}"); + this.subtype.add(SubType.ZOMBIE); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Menace + this.addAbility(new MenaceAbility(false)); + + // When Rot Hulk enters the battlefield, return up to X target Zombie cards from your graveyard to the battlefield, where X is the number of opponents you have. + Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect(); + effect.setText("return up to X target Zombie cards from your graveyard to the battlefield, where X is the number of opponents you have."); + Ability ability = new EntersBattlefieldTriggeredAbility(effect); + ability.addTarget(new TargetCardInYourGraveyard()); + entersBattlefieldAbilityID = ability.getOriginalId(); // adjust targets + this.addAbility(ability); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability.getOriginalId().equals(entersBattlefieldAbilityID)) { + // up to X target Zombie cards from your graveyard + // X is the number of opponents you have. + ability.getTargets().clear(); + int numbTargets = new OpponentsCount().calculate(game, ability, null); + ability.addTarget(new TargetCardInYourGraveyard(0, numbTargets, filterZombie)); + } + } + + public RotHulk(final RotHulk card) { + super(card); + this.entersBattlefieldAbilityID = card.entersBattlefieldAbilityID; + } + + @Override + public RotHulk copy() { + return new RotHulk(this); + } +} diff --git a/Mage.Sets/src/mage/sets/GameNight.java b/Mage.Sets/src/mage/sets/GameNight.java index cfb9b33749..9369f6913f 100644 --- a/Mage.Sets/src/mage/sets/GameNight.java +++ b/Mage.Sets/src/mage/sets/GameNight.java @@ -70,7 +70,7 @@ public final class GameNight extends ExpansionSet { cards.add(new SetCardInfo("Reckless Scholar", 23, Rarity.UNCOMMON, mage.cards.r.RecklessScholar.class)); cards.add(new SetCardInfo("Rhonas's Monument", 56, Rarity.UNCOMMON, mage.cards.r.RhonassMonument.class)); cards.add(new SetCardInfo("Rolling Thunder", 40, Rarity.UNCOMMON, mage.cards.r.RollingThunder.class)); - // TODO: cards.add(new SetCardInfo("Rot Hulk", 3, Rarity.MYTHIC, mage.cards.r.RotHulk.class)); + cards.add(new SetCardInfo("Rot Hulk", 3, Rarity.MYTHIC, mage.cards.r.RotHulk.class)); cards.add(new SetCardInfo("Seek the Wilds", 49, Rarity.COMMON, mage.cards.s.SeekTheWilds.class)); cards.add(new SetCardInfo("Seismic Elemental", 41, Rarity.UNCOMMON, mage.cards.s.SeismicElemental.class)); cards.add(new SetCardInfo("Serra Angel", 16, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class)); From c22217c22c8607e2c9cc3326eb02db1ef9e2adb4 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 12 Nov 2018 17:15:45 -0600 Subject: [PATCH 123/167] - Added Enchantment Alteration --- .../mage/cards/e/EnchantmentAlteration.java | 145 ++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 1 + 2 files changed, 146 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EnchantmentAlteration.java diff --git a/Mage.Sets/src/mage/cards/e/EnchantmentAlteration.java b/Mage.Sets/src/mage/cards/e/EnchantmentAlteration.java new file mode 100644 index 0000000000..c0594751a6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EnchantmentAlteration.java @@ -0,0 +1,145 @@ +package mage.cards.e; + +import java.util.UUID; +import mage.MageItem; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AttachmentAttachedToCardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; + +/** + * + * @author jeffwadsworth + */ +public final class EnchantmentAlteration extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("aura attached to a creature or land"); + private static final FilterPermanent filter2 = new FilterPermanent("another target permanent that shares that type of creature or land"); + + static { + filter.add(new SubtypePredicate(SubType.AURA)); + filter.add(Predicates.or(new AttachmentAttachedToCardTypePredicate(CardType.CREATURE), + new AttachmentAttachedToCardTypePredicate(CardType.LAND))); + filter2.add(new SharesEnchantedCardTypePredicate()); + // another target permanent is handled in this predicate + } + + public EnchantmentAlteration(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); + + // Attach target Aura attached to a creature or land to another permanent of that type. + this.getSpellAbility().addEffect(new EnchantmentAlterationEffect()); + TargetPermanent targetAura = new TargetPermanent(filter); + this.getSpellAbility().addTarget(targetAura); + + TargetPermanent targetCreatureOrLandThatSharesTheEnchantedCardType = new TargetPermanent(filter2); + this.getSpellAbility().addTarget(targetCreatureOrLandThatSharesTheEnchantedCardType); + + } + + public EnchantmentAlteration(final EnchantmentAlteration card) { + super(card); + } + + @Override + public EnchantmentAlteration copy() { + return new EnchantmentAlteration(this); + } + +} + +class SharesEnchantedCardTypePredicate implements ObjectSourcePlayerPredicate> { + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + StackObject source = game.getStack().getStackObject(input.getSourceId()); + Permanent auraIsAttachedToThisPermanent = null; + Permanent newPermanentToAttachAuraTo; + if (source != null) { + if (source.getStackAbility().getTargets().isEmpty() + || source.getStackAbility().getTargets().get(0).getTargets().isEmpty()) { + return true; + } + Permanent auraPermanent = game.getPermanent( + source.getStackAbility().getTargets().get(0).getTargets().get(0)); // targeted aura enchanting land or creature + if (auraPermanent != null) { + auraIsAttachedToThisPermanent = game.getPermanent(auraPermanent.getAttachedTo()); + } + if (auraIsAttachedToThisPermanent == null) { // the original permanent the aura is attached to + return false; + } + newPermanentToAttachAuraTo = game.getPermanent(input.getObject().getId()); // the new target creature or land to enchant + if (newPermanentToAttachAuraTo == auraIsAttachedToThisPermanent) { + return false; // must be another permanent + } + if (auraIsAttachedToThisPermanent.isCreature() + && newPermanentToAttachAuraTo.isCreature()) { + return true; + } + if (auraIsAttachedToThisPermanent.isLand() + && newPermanentToAttachAuraTo.isLand()) { + return true; + } + return false; + } + return true; + } + +} + +class EnchantmentAlterationEffect extends OneShotEffect { + + public EnchantmentAlterationEffect() { + super(Outcome.BoostCreature); + this.staticText = "Attach target Aura attached to a creature or land to another permanent of that type"; + } + + public EnchantmentAlterationEffect(final EnchantmentAlterationEffect effect) { + super(effect); + } + + @Override + public EnchantmentAlterationEffect copy() { + return new EnchantmentAlterationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent aura = game.getPermanent(source.getFirstTarget()); + Permanent permanentToBeAttachedTo = game.getPermanent(source.getTargets().get(1).getFirstTarget()); + if (aura != null + && permanentToBeAttachedTo != null) { + Permanent oldPermanent = game.getPermanent(aura.getAttachedTo()); + if (oldPermanent != null + && !oldPermanent.equals(permanentToBeAttachedTo)) { + Target auraTarget = aura.getSpellAbility().getTargets().get(0); + if (!auraTarget.canTarget(permanentToBeAttachedTo.getId(), game)) { + game.informPlayers(aura.getLogName() + " was not attched to " + permanentToBeAttachedTo.getLogName() + " because it's no legal target for the aura"); + } else if (oldPermanent.removeAttachment(aura.getId(), game)) { + game.informPlayers(aura.getLogName() + " was unattached from " + oldPermanent.getLogName() + " and attached to " + permanentToBeAttachedTo.getLogName()); + permanentToBeAttachedTo.addAttachment(aura.getId(), game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index a9945c10fc..45b950c405 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -111,6 +111,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Elite Archers", 13, Rarity.RARE, mage.cards.e.EliteArchers.class)); cards.add(new SetCardInfo("Elvish Herder", 247, Rarity.COMMON, mage.cards.e.ElvishHerder.class)); cards.add(new SetCardInfo("Elvish Lyrist", 248, Rarity.COMMON, mage.cards.e.ElvishLyrist.class)); + cards.add(new SetCardInfo("Enchantment Alteration", 72, Rarity.UNCOMMON, mage.cards.e.EnchantmentAlteration.class)); cards.add(new SetCardInfo("Endless Wurm", 249, Rarity.RARE, mage.cards.e.EndlessWurm.class)); cards.add(new SetCardInfo("Endoskeleton", 294, Rarity.UNCOMMON, mage.cards.e.Endoskeleton.class)); cards.add(new SetCardInfo("Energy Field", 73, Rarity.RARE, mage.cards.e.EnergyField.class)); From 2ebe05c85eac4ea91a0ff2c8c860a69859699e87 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 13 Nov 2018 03:20:20 +0400 Subject: [PATCH 124/167] [GNT] implemented Goblin Goliath, GNT set now fully implemented --- Mage.Sets/src/mage/cards/g/GoblinGoliath.java | 105 ++++++++++++++++++ Mage.Sets/src/mage/sets/GameNight.java | 5 +- .../cards/continuous/GoblinGoliathTest.java | 47 ++++++++ 3 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinGoliath.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/continuous/GoblinGoliathTest.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinGoliath.java b/Mage.Sets/src/mage/cards/g/GoblinGoliath.java new file mode 100644 index 0000000000..b8ac5dc92c --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinGoliath.java @@ -0,0 +1,105 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.OpponentsCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.GoblinToken; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class GoblinGoliath extends CardImpl { + + public GoblinGoliath(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.MUTANT); + + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // When Goblin Goliath enters the battlefield, create a number of 1/1 red Goblin creature tokens equal to the number of opponents you have. + Effect effect = new CreateTokenEffect(new GoblinToken(), new OpponentsCount()); + effect.setText("create a number of 1/1 red Goblin creature tokens equal to the number of opponents you have"); + this.addAbility(new EntersBattlefieldTriggeredAbility(effect)); + + // {3}{R}, {T}: If a source you control would deal damage to an opponent this turn, it deals double that damage to that player instead. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GoblinGoliathDamageEffect(), new ManaCostsImpl("{3}{R}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + public GoblinGoliath(final GoblinGoliath card) { + super(card); + } + + @Override + public GoblinGoliath copy() { + return new GoblinGoliath(this); + } +} + +class GoblinGoliathDamageEffect extends ReplacementEffectImpl { + + public GoblinGoliathDamageEffect() { + super(Duration.EndOfTurn, Outcome.Damage); + staticText = "If a source you control would deal damage to an opponent this turn, it deals double that damage to that player instead."; + } + + public GoblinGoliathDamageEffect(final GoblinGoliathDamageEffect effect) { + super(effect); + } + + @Override + public GoblinGoliathDamageEffect copy() { + return new GoblinGoliathDamageEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + UUID sourceControllerID = source.getControllerId(); + UUID damageControllerID = game.getControllerId(event.getSourceId()); + UUID damageTargetID = event.getTargetId(); + if (sourceControllerID != null && damageControllerID != null && damageTargetID != null) { + // our damage + if (damageControllerID.equals(sourceControllerID)) { + // to opponent only + if (game.getOpponents(sourceControllerID).contains(damageTargetID)) { + return true; + } + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/GameNight.java b/Mage.Sets/src/mage/sets/GameNight.java index 9369f6913f..84631bf8ac 100644 --- a/Mage.Sets/src/mage/sets/GameNight.java +++ b/Mage.Sets/src/mage/sets/GameNight.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.ExpansionSet; @@ -43,7 +42,7 @@ public final class GameNight extends ExpansionSet { cards.add(new SetCardInfo("Forest", 67, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 68, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ghalta, Primal Hunger", 44, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class)); - // TODO: cards.add(new SetCardInfo("Goblin Goliath", 4, Rarity.MYTHIC, mage.cards.g.GoblinGoliath.class)); + cards.add(new SetCardInfo("Goblin Goliath", 4, Rarity.MYTHIC, mage.cards.g.GoblinGoliath.class)); cards.add(new SetCardInfo("Gruesome Fate", 30, Rarity.COMMON, mage.cards.g.GruesomeFate.class)); cards.add(new SetCardInfo("Howling Golem", 53, Rarity.UNCOMMON, mage.cards.h.HowlingGolem.class)); cards.add(new SetCardInfo("Hydrolash", 22, Rarity.UNCOMMON, mage.cards.h.Hydrolash.class)); @@ -89,4 +88,4 @@ public final class GameNight extends ExpansionSet { cards.add(new SetCardInfo("Zahid, Djinn of the Lamp", 26, Rarity.RARE, mage.cards.z.ZahidDjinnOfTheLamp.class)); cards.add(new SetCardInfo("Zulaport Cutthroat", 36, Rarity.UNCOMMON, mage.cards.z.ZulaportCutthroat.class)); } -} +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/GoblinGoliathTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/GoblinGoliathTest.java new file mode 100644 index 0000000000..b3151c9535 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/GoblinGoliathTest.java @@ -0,0 +1,47 @@ +package org.mage.test.cards.continuous; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ +public class GoblinGoliathTest extends CardTestPlayerBase { + + @Test + public void test_DoubleDamage() { + // test double damage on creature (no), on yourself (no) and on opponent (yes) by bold damage + + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 20); + // {3}{R}, {T}: If a source you control would deal damage to an opponent this turn, it deals double that damage to that player instead. + addCard(Zone.BATTLEFIELD, playerA, "Goblin Goliath"); + addCard(Zone.HAND, playerA, "Lightning Bolt", 4); // 3 damage + addCard(Zone.BATTLEFIELD, playerB, "Barktooth Warbeard"); // 6/5 + + // normal damage without ability + castSpell(1, PhaseStep.UPKEEP, playerA, "Lightning Bolt", playerB); + checkLife("normal damage to opponent", 1, PhaseStep.PRECOMBAT_MAIN, playerB, 20 - 3); + + // activate double damage + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{3}{R}"); + // cast bolt to player (2x damage) + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Lightning Bolt", playerB); + checkLife("double damage to opponent", 1, PhaseStep.END_COMBAT, playerB, 20 - 3 - 3 * 2); + // cast bolt to creature (1x damage) + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Lightning Bolt", "Barktooth Warbeard"); + checkPermanentCount("normal damage to creature", 1, PhaseStep.END_COMBAT, playerB, "Barktooth Warbeard", 1); + // cast bolt to yourself (1x damage) + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Lightning Bolt", playerA); + checkLife("normal damage to yourself", 1, PhaseStep.END_COMBAT, playerA, 20 - 3); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertGraveyardCount(playerA, "Lightning Bolt", 4); + assertLife(playerA, 20 - 3); + assertLife(playerB, 20 - 3 - 3 * 2); + assertGraveyardCount(playerB, "Barktooth Warbeard", 0); + } +} \ No newline at end of file From e953f5e2ccf37350b8d68af4bc72883af8926249 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 12 Nov 2018 17:21:37 -0600 Subject: [PATCH 125/167] - Modified 2 sets to include new card --- Mage.Sets/src/mage/sets/Chronicles.java | 295 ++++++------ Mage.Sets/src/mage/sets/Legends.java | 591 ++++++++++++------------ 2 files changed, 444 insertions(+), 442 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Chronicles.java b/Mage.Sets/src/mage/sets/Chronicles.java index 03cde6e56d..050f42904b 100644 --- a/Mage.Sets/src/mage/sets/Chronicles.java +++ b/Mage.Sets/src/mage/sets/Chronicles.java @@ -1,147 +1,148 @@ -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author LevelX2 - */ -public final class Chronicles extends ExpansionSet { - - private static final Chronicles instance = new Chronicles(); - - public static Chronicles getInstance() { - return instance; - } - - private Chronicles() { - super("Chronicles", "CHR", ExpansionSet.buildDate(1995, 6, 1), SetType.SUPPLEMENTAL); - this.blockName = "Reprint"; - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 9; - this.numBoosterUncommon = 2; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Abu Ja'far", 57, Rarity.UNCOMMON, mage.cards.a.AbuJafar.class)); - cards.add(new SetCardInfo("Active Volcano", 43, Rarity.COMMON, mage.cards.a.ActiveVolcano.class)); - cards.add(new SetCardInfo("Akron Legionnaire", 58, Rarity.RARE, mage.cards.a.AkronLegionnaire.class)); - cards.add(new SetCardInfo("Aladdin", 44, Rarity.UNCOMMON, mage.cards.a.Aladdin.class)); - cards.add(new SetCardInfo("Angelic Voices", 59, Rarity.RARE, mage.cards.a.AngelicVoices.class)); - cards.add(new SetCardInfo("Arcades Sabboth", 106, Rarity.RARE, mage.cards.a.ArcadesSabboth.class)); - cards.add(new SetCardInfo("Arena of the Ancients", 71, Rarity.RARE, mage.cards.a.ArenaOfTheAncients.class)); - cards.add(new SetCardInfo("Argothian Pixies", 29, Rarity.COMMON, mage.cards.a.ArgothianPixies.class)); - cards.add(new SetCardInfo("Ashnod's Altar", 72, Rarity.COMMON, mage.cards.a.AshnodsAltar.class)); - cards.add(new SetCardInfo("Ashnod's Transmogrant", 73, Rarity.COMMON, mage.cards.a.AshnodsTransmogrant.class)); - cards.add(new SetCardInfo("Axelrod Gunnarson", 107, Rarity.RARE, mage.cards.a.AxelrodGunnarson.class)); - cards.add(new SetCardInfo("Ayesha Tanaka", 108, Rarity.RARE, mage.cards.a.AyeshaTanaka.class)); - cards.add(new SetCardInfo("Azure Drake", 15, Rarity.UNCOMMON, mage.cards.a.AzureDrake.class)); - cards.add(new SetCardInfo("Banshee", 1, Rarity.UNCOMMON, mage.cards.b.Banshee.class)); - cards.add(new SetCardInfo("Barl's Cage", 74, Rarity.RARE, mage.cards.b.BarlsCage.class)); - cards.add(new SetCardInfo("Beasts of Bogardan", 45, Rarity.UNCOMMON, mage.cards.b.BeastsOfBogardan.class)); - cards.add(new SetCardInfo("Blood Moon", 46, Rarity.RARE, mage.cards.b.BloodMoon.class)); - cards.add(new SetCardInfo("Blood of the Martyr", 60, Rarity.UNCOMMON, mage.cards.b.BloodOfTheMartyr.class)); - cards.add(new SetCardInfo("Bog Rats", 2, Rarity.COMMON, mage.cards.b.BogRats.class)); - cards.add(new SetCardInfo("Book of Rass", 75, Rarity.RARE, mage.cards.b.BookOfRass.class)); - cards.add(new SetCardInfo("Boomerang", 16, Rarity.COMMON, mage.cards.b.Boomerang.class)); - cards.add(new SetCardInfo("Cat Warriors", 30, Rarity.COMMON, mage.cards.c.CatWarriors.class)); - cards.add(new SetCardInfo("Chromium", 109, Rarity.RARE, mage.cards.c.Chromium.class)); - cards.add(new SetCardInfo("City of Brass", 92, Rarity.RARE, mage.cards.c.CityOfBrass.class)); - cards.add(new SetCardInfo("Concordant Crossroads", 32, Rarity.RARE, mage.cards.c.ConcordantCrossroads.class)); - cards.add(new SetCardInfo("Craw Giant", 33, Rarity.UNCOMMON, mage.cards.c.CrawGiant.class)); - cards.add(new SetCardInfo("Cuombajj Witches", 3, Rarity.COMMON, mage.cards.c.CuombajjWitches.class)); - cards.add(new SetCardInfo("Cyclone", 34, Rarity.RARE, mage.cards.c.Cyclone.class)); - cards.add(new SetCardInfo("Dakkon Blackblade", 110, Rarity.RARE, mage.cards.d.DakkonBlackblade.class)); - cards.add(new SetCardInfo("Dance of Many", 17, Rarity.RARE, mage.cards.d.DanceOfMany.class)); - cards.add(new SetCardInfo("Dandan", 18, Rarity.COMMON, mage.cards.d.Dandan.class)); - cards.add(new SetCardInfo("D'Avenant Archer", 61, Rarity.COMMON, mage.cards.d.DAvenantArcher.class)); - cards.add(new SetCardInfo("Divine Offering", 62, Rarity.COMMON, mage.cards.d.DivineOffering.class)); - cards.add(new SetCardInfo("Emerald Dragonfly", 35, Rarity.COMMON, mage.cards.e.EmeraldDragonfly.class)); - cards.add(new SetCardInfo("Erhnam Djinn", 36, Rarity.UNCOMMON, mage.cards.e.ErhnamDjinn.class)); - cards.add(new SetCardInfo("Fallen Angel", 4, Rarity.UNCOMMON, mage.cards.f.FallenAngel.class)); - cards.add(new SetCardInfo("Feldon's Cane", 77, Rarity.COMMON, mage.cards.f.FeldonsCane.class)); - cards.add(new SetCardInfo("Fire Drake", 47, Rarity.UNCOMMON, mage.cards.f.FireDrake.class)); - cards.add(new SetCardInfo("Fishliver Oil", 20, Rarity.COMMON, mage.cards.f.FishliverOil.class)); - cards.add(new SetCardInfo("Flash Flood", 21, Rarity.COMMON, mage.cards.f.FlashFlood.class)); - cards.add(new SetCardInfo("Fountain of Youth", 78, Rarity.COMMON, mage.cards.f.FountainOfYouth.class)); - cards.add(new SetCardInfo("Gabriel Angelfire", 111, Rarity.RARE, mage.cards.g.GabrielAngelfire.class)); - cards.add(new SetCardInfo("Gauntlets of Chaos", 79, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class)); - cards.add(new SetCardInfo("Ghazban Ogre", 37, Rarity.COMMON, mage.cards.g.GhazbanOgre.class)); - cards.add(new SetCardInfo("Goblin Artisans", 48, Rarity.UNCOMMON, mage.cards.g.GoblinArtisans.class)); - cards.add(new SetCardInfo("Goblin Digging Team", 49, Rarity.COMMON, mage.cards.g.GoblinDiggingTeam.class)); - cards.add(new SetCardInfo("Goblin Shrine", 50, Rarity.COMMON, mage.cards.g.GoblinShrine.class)); - cards.add(new SetCardInfo("Goblins of the Flarg", 51, Rarity.COMMON, mage.cards.g.GoblinsOfTheFlarg.class)); - cards.add(new SetCardInfo("Hasran Ogress", 6, Rarity.COMMON, mage.cards.h.HasranOgress.class)); - cards.add(new SetCardInfo("Hell's Caretaker", 7, Rarity.RARE, mage.cards.h.HellsCaretaker.class)); - cards.add(new SetCardInfo("Horn of Deafening", 80, Rarity.RARE, mage.cards.h.HornOfDeafening.class)); - cards.add(new SetCardInfo("Indestructible Aura", 63, Rarity.COMMON, mage.cards.i.IndestructibleAura.class)); - cards.add(new SetCardInfo("Ivory Guardians", 64, Rarity.UNCOMMON, mage.cards.i.IvoryGuardians.class)); - cards.add(new SetCardInfo("Jalum Tome", 81, Rarity.RARE, mage.cards.j.JalumTome.class)); - cards.add(new SetCardInfo("Johan", 112, Rarity.RARE, mage.cards.j.Johan.class)); - cards.add(new SetCardInfo("Juxtapose", 22, Rarity.RARE, mage.cards.j.Juxtapose.class)); - cards.add(new SetCardInfo("Keepers of the Faith", 65, Rarity.COMMON, mage.cards.k.KeepersOfTheFaith.class)); - cards.add(new SetCardInfo("Kei Takahashi", 113, Rarity.UNCOMMON, mage.cards.k.KeiTakahashi.class)); - cards.add(new SetCardInfo("Land's Edge", 52, Rarity.RARE, mage.cards.l.LandsEdge.class)); - cards.add(new SetCardInfo("Living Armor", 83, Rarity.COMMON, mage.cards.l.LivingArmor.class)); - cards.add(new SetCardInfo("Marhault Elsdragon", 114, Rarity.UNCOMMON, mage.cards.m.MarhaultElsdragon.class)); - cards.add(new SetCardInfo("Metamorphosis", 38, Rarity.COMMON, mage.cards.m.Metamorphosis.class)); - cards.add(new SetCardInfo("Mountain Yeti", 53, Rarity.COMMON, mage.cards.m.MountainYeti.class)); - cards.add(new SetCardInfo("Nebuchadnezzar", 115, Rarity.RARE, mage.cards.n.Nebuchadnezzar.class)); - cards.add(new SetCardInfo("Nicol Bolas", 116, Rarity.RARE, mage.cards.n.NicolBolas.class)); - cards.add(new SetCardInfo("Obelisk of Undoing", 84, Rarity.RARE, mage.cards.o.ObeliskOfUndoing.class)); - cards.add(new SetCardInfo("Palladia-Mors", 117, Rarity.RARE, mage.cards.p.PalladiaMors.class)); - cards.add(new SetCardInfo("Petra Sphinx", 66, Rarity.RARE, mage.cards.p.PetraSphinx.class)); - cards.add(new SetCardInfo("Primordial Ooze", 54, Rarity.UNCOMMON, mage.cards.p.PrimordialOoze.class)); - cards.add(new SetCardInfo("Rabid Wombat", 39, Rarity.UNCOMMON, mage.cards.r.RabidWombat.class)); - cards.add(new SetCardInfo("Rakalite", 85, Rarity.RARE, mage.cards.r.Rakalite.class)); - cards.add(new SetCardInfo("Recall", 24, Rarity.UNCOMMON, mage.cards.r.Recall.class)); - cards.add(new SetCardInfo("Remove Soul", 25, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); - cards.add(new SetCardInfo("Repentant Blacksmith", 67, Rarity.COMMON, mage.cards.r.RepentantBlacksmith.class)); - cards.add(new SetCardInfo("Revelation", 40, Rarity.RARE, mage.cards.r.Revelation.class)); - cards.add(new SetCardInfo("Rubinia Soulsinger", 118, Rarity.RARE, mage.cards.r.RubiniaSoulsinger.class)); - cards.add(new SetCardInfo("Runesword", 86, Rarity.COMMON, mage.cards.r.Runesword.class)); - cards.add(new SetCardInfo("Safe Haven", 93, Rarity.RARE, mage.cards.s.SafeHaven.class)); - cards.add(new SetCardInfo("Scavenger Folk", 41, Rarity.COMMON, mage.cards.s.ScavengerFolk.class)); - cards.add(new SetCardInfo("Sentinel", 87, Rarity.RARE, mage.cards.s.Sentinel.class)); - cards.add(new SetCardInfo("Serpent Generator", 88, Rarity.RARE, mage.cards.s.SerpentGenerator.class)); - cards.add(new SetCardInfo("Shield Wall", 68, Rarity.UNCOMMON, mage.cards.s.ShieldWall.class)); - cards.add(new SetCardInfo("Shimian Night Stalker", 8, Rarity.UNCOMMON, mage.cards.s.ShimianNightStalker.class)); - cards.add(new SetCardInfo("Sivitri Scarzam", 119, Rarity.UNCOMMON, mage.cards.s.SivitriScarzam.class)); - cards.add(new SetCardInfo("Sol'kanar the Swamp King", 120, Rarity.RARE, mage.cards.s.SolkanarTheSwampKing.class)); - cards.add(new SetCardInfo("Stangg", 121, Rarity.RARE, mage.cards.s.Stangg.class)); - cards.add(new SetCardInfo("Storm Seeker", 42, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class)); - cards.add(new SetCardInfo("Teleport", 26, Rarity.RARE, mage.cards.t.Teleport.class)); - cards.add(new SetCardInfo("The Fallen", 10, Rarity.UNCOMMON, mage.cards.t.TheFallen.class)); - cards.add(new SetCardInfo("The Wretched", 11, Rarity.RARE, mage.cards.t.TheWretched.class)); - cards.add(new SetCardInfo("Tobias Andrion", 122, Rarity.UNCOMMON, mage.cards.t.TobiasAndrion.class)); - cards.add(new SetCardInfo("Tormod's Crypt", 89, Rarity.COMMON, mage.cards.t.TormodsCrypt.class)); - cards.add(new SetCardInfo("Tor Wauki", 123, Rarity.UNCOMMON, mage.cards.t.TorWauki.class)); - cards.add(new SetCardInfo("Transmutation", 12, Rarity.COMMON, mage.cards.t.Transmutation.class)); - cards.add(new SetCardInfo("Triassic Egg", 90, Rarity.RARE, mage.cards.t.TriassicEgg.class)); - cards.add(new SetCardInfo("Urza's Mine", 94, Rarity.UNCOMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Mine", 95, Rarity.UNCOMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Mine", 96, Rarity.UNCOMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Mine", 97, Rarity.UNCOMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Power Plant", 98, Rarity.UNCOMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Power Plant", 99, Rarity.UNCOMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Power Plant", 100, Rarity.UNCOMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Power Plant", 101, Rarity.UNCOMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Tower", 102, Rarity.UNCOMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Tower", 103, Rarity.UNCOMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Tower", 104, Rarity.UNCOMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Tower", 105, Rarity.UNCOMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vaevictis Asmadi", 124, Rarity.RARE, mage.cards.v.VaevictisAsmadi.class)); - cards.add(new SetCardInfo("Wall of Heat", 55, Rarity.COMMON, mage.cards.w.WallOfHeat.class)); - cards.add(new SetCardInfo("Wall of Opposition", 56, Rarity.UNCOMMON, mage.cards.w.WallOfOpposition.class)); - cards.add(new SetCardInfo("Wall of Vapor", 27, Rarity.COMMON, mage.cards.w.WallOfVapor.class)); - cards.add(new SetCardInfo("Wall of Wonder", 28, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class)); - cards.add(new SetCardInfo("War Elephant", 69, Rarity.COMMON, mage.cards.w.WarElephant.class)); - cards.add(new SetCardInfo("Witch Hunter", 70, Rarity.UNCOMMON, mage.cards.w.WitchHunter.class)); - cards.add(new SetCardInfo("Xira Arien", 125, Rarity.RARE, mage.cards.x.XiraArien.class)); - cards.add(new SetCardInfo("Yawgmoth Demon", 14, Rarity.RARE, mage.cards.y.YawgmothDemon.class)); - } - -} +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author LevelX2 + */ +public final class Chronicles extends ExpansionSet { + + private static final Chronicles instance = new Chronicles(); + + public static Chronicles getInstance() { + return instance; + } + + private Chronicles() { + super("Chronicles", "CHR", ExpansionSet.buildDate(1995, 6, 1), SetType.SUPPLEMENTAL); + this.blockName = "Reprint"; + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 9; + this.numBoosterUncommon = 2; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abu Ja'far", 57, Rarity.UNCOMMON, mage.cards.a.AbuJafar.class)); + cards.add(new SetCardInfo("Active Volcano", 43, Rarity.COMMON, mage.cards.a.ActiveVolcano.class)); + cards.add(new SetCardInfo("Akron Legionnaire", 58, Rarity.RARE, mage.cards.a.AkronLegionnaire.class)); + cards.add(new SetCardInfo("Aladdin", 44, Rarity.UNCOMMON, mage.cards.a.Aladdin.class)); + cards.add(new SetCardInfo("Angelic Voices", 59, Rarity.RARE, mage.cards.a.AngelicVoices.class)); + cards.add(new SetCardInfo("Arcades Sabboth", 106, Rarity.RARE, mage.cards.a.ArcadesSabboth.class)); + cards.add(new SetCardInfo("Arena of the Ancients", 71, Rarity.RARE, mage.cards.a.ArenaOfTheAncients.class)); + cards.add(new SetCardInfo("Argothian Pixies", 29, Rarity.COMMON, mage.cards.a.ArgothianPixies.class)); + cards.add(new SetCardInfo("Ashnod's Altar", 72, Rarity.COMMON, mage.cards.a.AshnodsAltar.class)); + cards.add(new SetCardInfo("Ashnod's Transmogrant", 73, Rarity.COMMON, mage.cards.a.AshnodsTransmogrant.class)); + cards.add(new SetCardInfo("Axelrod Gunnarson", 107, Rarity.RARE, mage.cards.a.AxelrodGunnarson.class)); + cards.add(new SetCardInfo("Ayesha Tanaka", 108, Rarity.RARE, mage.cards.a.AyeshaTanaka.class)); + cards.add(new SetCardInfo("Azure Drake", 15, Rarity.UNCOMMON, mage.cards.a.AzureDrake.class)); + cards.add(new SetCardInfo("Banshee", 1, Rarity.UNCOMMON, mage.cards.b.Banshee.class)); + cards.add(new SetCardInfo("Barl's Cage", 74, Rarity.RARE, mage.cards.b.BarlsCage.class)); + cards.add(new SetCardInfo("Beasts of Bogardan", 45, Rarity.UNCOMMON, mage.cards.b.BeastsOfBogardan.class)); + cards.add(new SetCardInfo("Blood Moon", 46, Rarity.RARE, mage.cards.b.BloodMoon.class)); + cards.add(new SetCardInfo("Blood of the Martyr", 60, Rarity.UNCOMMON, mage.cards.b.BloodOfTheMartyr.class)); + cards.add(new SetCardInfo("Bog Rats", 2, Rarity.COMMON, mage.cards.b.BogRats.class)); + cards.add(new SetCardInfo("Book of Rass", 75, Rarity.RARE, mage.cards.b.BookOfRass.class)); + cards.add(new SetCardInfo("Boomerang", 16, Rarity.COMMON, mage.cards.b.Boomerang.class)); + cards.add(new SetCardInfo("Cat Warriors", 30, Rarity.COMMON, mage.cards.c.CatWarriors.class)); + cards.add(new SetCardInfo("Chromium", 109, Rarity.RARE, mage.cards.c.Chromium.class)); + cards.add(new SetCardInfo("City of Brass", 92, Rarity.RARE, mage.cards.c.CityOfBrass.class)); + cards.add(new SetCardInfo("Concordant Crossroads", 32, Rarity.RARE, mage.cards.c.ConcordantCrossroads.class)); + cards.add(new SetCardInfo("Craw Giant", 33, Rarity.UNCOMMON, mage.cards.c.CrawGiant.class)); + cards.add(new SetCardInfo("Cuombajj Witches", 3, Rarity.COMMON, mage.cards.c.CuombajjWitches.class)); + cards.add(new SetCardInfo("Cyclone", 34, Rarity.RARE, mage.cards.c.Cyclone.class)); + cards.add(new SetCardInfo("Dakkon Blackblade", 110, Rarity.RARE, mage.cards.d.DakkonBlackblade.class)); + cards.add(new SetCardInfo("Dance of Many", 17, Rarity.RARE, mage.cards.d.DanceOfMany.class)); + cards.add(new SetCardInfo("Dandan", 18, Rarity.COMMON, mage.cards.d.Dandan.class)); + cards.add(new SetCardInfo("D'Avenant Archer", 61, Rarity.COMMON, mage.cards.d.DAvenantArcher.class)); + cards.add(new SetCardInfo("Divine Offering", 62, Rarity.COMMON, mage.cards.d.DivineOffering.class)); + cards.add(new SetCardInfo("Emerald Dragonfly", 35, Rarity.COMMON, mage.cards.e.EmeraldDragonfly.class)); + cards.add(new SetCardInfo("Enchantment Alteration", 19, Rarity.UNCOMMON, mage.cards.e.EnchantmentAlteration.class)); + cards.add(new SetCardInfo("Erhnam Djinn", 36, Rarity.UNCOMMON, mage.cards.e.ErhnamDjinn.class)); + cards.add(new SetCardInfo("Fallen Angel", 4, Rarity.UNCOMMON, mage.cards.f.FallenAngel.class)); + cards.add(new SetCardInfo("Feldon's Cane", 77, Rarity.COMMON, mage.cards.f.FeldonsCane.class)); + cards.add(new SetCardInfo("Fire Drake", 47, Rarity.UNCOMMON, mage.cards.f.FireDrake.class)); + cards.add(new SetCardInfo("Fishliver Oil", 20, Rarity.COMMON, mage.cards.f.FishliverOil.class)); + cards.add(new SetCardInfo("Flash Flood", 21, Rarity.COMMON, mage.cards.f.FlashFlood.class)); + cards.add(new SetCardInfo("Fountain of Youth", 78, Rarity.COMMON, mage.cards.f.FountainOfYouth.class)); + cards.add(new SetCardInfo("Gabriel Angelfire", 111, Rarity.RARE, mage.cards.g.GabrielAngelfire.class)); + cards.add(new SetCardInfo("Gauntlets of Chaos", 79, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class)); + cards.add(new SetCardInfo("Ghazban Ogre", 37, Rarity.COMMON, mage.cards.g.GhazbanOgre.class)); + cards.add(new SetCardInfo("Goblin Artisans", 48, Rarity.UNCOMMON, mage.cards.g.GoblinArtisans.class)); + cards.add(new SetCardInfo("Goblin Digging Team", 49, Rarity.COMMON, mage.cards.g.GoblinDiggingTeam.class)); + cards.add(new SetCardInfo("Goblin Shrine", 50, Rarity.COMMON, mage.cards.g.GoblinShrine.class)); + cards.add(new SetCardInfo("Goblins of the Flarg", 51, Rarity.COMMON, mage.cards.g.GoblinsOfTheFlarg.class)); + cards.add(new SetCardInfo("Hasran Ogress", 6, Rarity.COMMON, mage.cards.h.HasranOgress.class)); + cards.add(new SetCardInfo("Hell's Caretaker", 7, Rarity.RARE, mage.cards.h.HellsCaretaker.class)); + cards.add(new SetCardInfo("Horn of Deafening", 80, Rarity.RARE, mage.cards.h.HornOfDeafening.class)); + cards.add(new SetCardInfo("Indestructible Aura", 63, Rarity.COMMON, mage.cards.i.IndestructibleAura.class)); + cards.add(new SetCardInfo("Ivory Guardians", 64, Rarity.UNCOMMON, mage.cards.i.IvoryGuardians.class)); + cards.add(new SetCardInfo("Jalum Tome", 81, Rarity.RARE, mage.cards.j.JalumTome.class)); + cards.add(new SetCardInfo("Johan", 112, Rarity.RARE, mage.cards.j.Johan.class)); + cards.add(new SetCardInfo("Juxtapose", 22, Rarity.RARE, mage.cards.j.Juxtapose.class)); + cards.add(new SetCardInfo("Keepers of the Faith", 65, Rarity.COMMON, mage.cards.k.KeepersOfTheFaith.class)); + cards.add(new SetCardInfo("Kei Takahashi", 113, Rarity.UNCOMMON, mage.cards.k.KeiTakahashi.class)); + cards.add(new SetCardInfo("Land's Edge", 52, Rarity.RARE, mage.cards.l.LandsEdge.class)); + cards.add(new SetCardInfo("Living Armor", 83, Rarity.COMMON, mage.cards.l.LivingArmor.class)); + cards.add(new SetCardInfo("Marhault Elsdragon", 114, Rarity.UNCOMMON, mage.cards.m.MarhaultElsdragon.class)); + cards.add(new SetCardInfo("Metamorphosis", 38, Rarity.COMMON, mage.cards.m.Metamorphosis.class)); + cards.add(new SetCardInfo("Mountain Yeti", 53, Rarity.COMMON, mage.cards.m.MountainYeti.class)); + cards.add(new SetCardInfo("Nebuchadnezzar", 115, Rarity.RARE, mage.cards.n.Nebuchadnezzar.class)); + cards.add(new SetCardInfo("Nicol Bolas", 116, Rarity.RARE, mage.cards.n.NicolBolas.class)); + cards.add(new SetCardInfo("Obelisk of Undoing", 84, Rarity.RARE, mage.cards.o.ObeliskOfUndoing.class)); + cards.add(new SetCardInfo("Palladia-Mors", 117, Rarity.RARE, mage.cards.p.PalladiaMors.class)); + cards.add(new SetCardInfo("Petra Sphinx", 66, Rarity.RARE, mage.cards.p.PetraSphinx.class)); + cards.add(new SetCardInfo("Primordial Ooze", 54, Rarity.UNCOMMON, mage.cards.p.PrimordialOoze.class)); + cards.add(new SetCardInfo("Rabid Wombat", 39, Rarity.UNCOMMON, mage.cards.r.RabidWombat.class)); + cards.add(new SetCardInfo("Rakalite", 85, Rarity.RARE, mage.cards.r.Rakalite.class)); + cards.add(new SetCardInfo("Recall", 24, Rarity.UNCOMMON, mage.cards.r.Recall.class)); + cards.add(new SetCardInfo("Remove Soul", 25, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); + cards.add(new SetCardInfo("Repentant Blacksmith", 67, Rarity.COMMON, mage.cards.r.RepentantBlacksmith.class)); + cards.add(new SetCardInfo("Revelation", 40, Rarity.RARE, mage.cards.r.Revelation.class)); + cards.add(new SetCardInfo("Rubinia Soulsinger", 118, Rarity.RARE, mage.cards.r.RubiniaSoulsinger.class)); + cards.add(new SetCardInfo("Runesword", 86, Rarity.COMMON, mage.cards.r.Runesword.class)); + cards.add(new SetCardInfo("Safe Haven", 93, Rarity.RARE, mage.cards.s.SafeHaven.class)); + cards.add(new SetCardInfo("Scavenger Folk", 41, Rarity.COMMON, mage.cards.s.ScavengerFolk.class)); + cards.add(new SetCardInfo("Sentinel", 87, Rarity.RARE, mage.cards.s.Sentinel.class)); + cards.add(new SetCardInfo("Serpent Generator", 88, Rarity.RARE, mage.cards.s.SerpentGenerator.class)); + cards.add(new SetCardInfo("Shield Wall", 68, Rarity.UNCOMMON, mage.cards.s.ShieldWall.class)); + cards.add(new SetCardInfo("Shimian Night Stalker", 8, Rarity.UNCOMMON, mage.cards.s.ShimianNightStalker.class)); + cards.add(new SetCardInfo("Sivitri Scarzam", 119, Rarity.UNCOMMON, mage.cards.s.SivitriScarzam.class)); + cards.add(new SetCardInfo("Sol'kanar the Swamp King", 120, Rarity.RARE, mage.cards.s.SolkanarTheSwampKing.class)); + cards.add(new SetCardInfo("Stangg", 121, Rarity.RARE, mage.cards.s.Stangg.class)); + cards.add(new SetCardInfo("Storm Seeker", 42, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class)); + cards.add(new SetCardInfo("Teleport", 26, Rarity.RARE, mage.cards.t.Teleport.class)); + cards.add(new SetCardInfo("The Fallen", 10, Rarity.UNCOMMON, mage.cards.t.TheFallen.class)); + cards.add(new SetCardInfo("The Wretched", 11, Rarity.RARE, mage.cards.t.TheWretched.class)); + cards.add(new SetCardInfo("Tobias Andrion", 122, Rarity.UNCOMMON, mage.cards.t.TobiasAndrion.class)); + cards.add(new SetCardInfo("Tormod's Crypt", 89, Rarity.COMMON, mage.cards.t.TormodsCrypt.class)); + cards.add(new SetCardInfo("Tor Wauki", 123, Rarity.UNCOMMON, mage.cards.t.TorWauki.class)); + cards.add(new SetCardInfo("Transmutation", 12, Rarity.COMMON, mage.cards.t.Transmutation.class)); + cards.add(new SetCardInfo("Triassic Egg", 90, Rarity.RARE, mage.cards.t.TriassicEgg.class)); + cards.add(new SetCardInfo("Urza's Mine", 94, Rarity.UNCOMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 95, Rarity.UNCOMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 96, Rarity.UNCOMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 97, Rarity.UNCOMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 98, Rarity.UNCOMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 99, Rarity.UNCOMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 100, Rarity.UNCOMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 101, Rarity.UNCOMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 102, Rarity.UNCOMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 103, Rarity.UNCOMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 104, Rarity.UNCOMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 105, Rarity.UNCOMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vaevictis Asmadi", 124, Rarity.RARE, mage.cards.v.VaevictisAsmadi.class)); + cards.add(new SetCardInfo("Wall of Heat", 55, Rarity.COMMON, mage.cards.w.WallOfHeat.class)); + cards.add(new SetCardInfo("Wall of Opposition", 56, Rarity.UNCOMMON, mage.cards.w.WallOfOpposition.class)); + cards.add(new SetCardInfo("Wall of Vapor", 27, Rarity.COMMON, mage.cards.w.WallOfVapor.class)); + cards.add(new SetCardInfo("Wall of Wonder", 28, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class)); + cards.add(new SetCardInfo("War Elephant", 69, Rarity.COMMON, mage.cards.w.WarElephant.class)); + cards.add(new SetCardInfo("Witch Hunter", 70, Rarity.UNCOMMON, mage.cards.w.WitchHunter.class)); + cards.add(new SetCardInfo("Xira Arien", 125, Rarity.RARE, mage.cards.x.XiraArien.class)); + cards.add(new SetCardInfo("Yawgmoth Demon", 14, Rarity.RARE, mage.cards.y.YawgmothDemon.class)); + } + +} diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index 987bc827dd..68a33d4974 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -1,295 +1,296 @@ -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author North - */ -public final class Legends extends ExpansionSet { - - private static final Legends instance = new Legends(); - - public static Legends getInstance() { - return instance; - } - - private Legends() { - super("Legends", "LEG", ExpansionSet.buildDate(1994, 6, 1), SetType.EXPANSION); - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Abomination", 87, Rarity.UNCOMMON, mage.cards.a.Abomination.class)); - cards.add(new SetCardInfo("Acid Rain", 44, Rarity.RARE, mage.cards.a.AcidRain.class)); - cards.add(new SetCardInfo("Active Volcano", 130, Rarity.COMMON, mage.cards.a.ActiveVolcano.class)); - cards.add(new SetCardInfo("Adun Oakenshield", 216, Rarity.RARE, mage.cards.a.AdunOakenshield.class)); - cards.add(new SetCardInfo("Aerathi Berserker", 131, Rarity.UNCOMMON, mage.cards.a.AerathiBerserker.class)); - cards.add(new SetCardInfo("Aisling Leprechaun", 173, Rarity.COMMON, mage.cards.a.AislingLeprechaun.class)); - cards.add(new SetCardInfo("Akron Legionnaire", 1, Rarity.RARE, mage.cards.a.AkronLegionnaire.class)); - cards.add(new SetCardInfo("Al-abara's Carpet", 271, Rarity.RARE, mage.cards.a.AlAbarasCarpet.class)); - cards.add(new SetCardInfo("Alabaster Potion", 2, Rarity.COMMON, mage.cards.a.AlabasterPotion.class)); - cards.add(new SetCardInfo("Alchor's Tomb", 272, Rarity.RARE, mage.cards.a.AlchorsTomb.class)); - cards.add(new SetCardInfo("All Hallow's Eve", 88, Rarity.RARE, mage.cards.a.AllHallowsEve.class)); - cards.add(new SetCardInfo("Amrou Kithkin", 3, Rarity.COMMON, mage.cards.a.AmrouKithkin.class)); - cards.add(new SetCardInfo("Angelic Voices", 4, Rarity.RARE, mage.cards.a.AngelicVoices.class)); - cards.add(new SetCardInfo("Angus Mackenzie", 217, Rarity.RARE, mage.cards.a.AngusMackenzie.class)); - cards.add(new SetCardInfo("Anti-Magic Aura", 45, Rarity.COMMON, mage.cards.a.AntiMagicAura.class)); - cards.add(new SetCardInfo("Arboria", 174, Rarity.UNCOMMON, mage.cards.a.Arboria.class)); - cards.add(new SetCardInfo("Arcades Sabboth", 218, Rarity.RARE, mage.cards.a.ArcadesSabboth.class)); - cards.add(new SetCardInfo("Arena of the Ancients", 273, Rarity.RARE, mage.cards.a.ArenaOfTheAncients.class)); - cards.add(new SetCardInfo("Avoid Fate", 175, Rarity.COMMON, mage.cards.a.AvoidFate.class)); - cards.add(new SetCardInfo("Axelrod Gunnarson", 219, Rarity.RARE, mage.cards.a.AxelrodGunnarson.class)); - cards.add(new SetCardInfo("Ayesha Tanaka", 220, Rarity.RARE, mage.cards.a.AyeshaTanaka.class)); - cards.add(new SetCardInfo("Azure Drake", 46, Rarity.UNCOMMON, mage.cards.a.AzureDrake.class)); - cards.add(new SetCardInfo("Backfire", 47, Rarity.UNCOMMON, mage.cards.b.Backfire.class)); - cards.add(new SetCardInfo("Barbary Apes", 176, Rarity.COMMON, mage.cards.b.BarbaryApes.class)); - cards.add(new SetCardInfo("Barktooth Warbeard", 221, Rarity.UNCOMMON, mage.cards.b.BarktoothWarbeard.class)); - cards.add(new SetCardInfo("Bartel Runeaxe", 222, Rarity.RARE, mage.cards.b.BartelRuneaxe.class)); - cards.add(new SetCardInfo("Beasts of Bogardan", 133, Rarity.UNCOMMON, mage.cards.b.BeastsOfBogardan.class)); - cards.add(new SetCardInfo("Black Mana Battery", 274, Rarity.UNCOMMON, mage.cards.b.BlackManaBattery.class)); - cards.add(new SetCardInfo("Blight", 89, Rarity.UNCOMMON, mage.cards.b.Blight.class)); - cards.add(new SetCardInfo("Blood Lust", 135, Rarity.UNCOMMON, mage.cards.b.BloodLust.class)); - cards.add(new SetCardInfo("Blue Mana Battery", 275, Rarity.UNCOMMON, mage.cards.b.BlueManaBattery.class)); - cards.add(new SetCardInfo("Boomerang", 48, Rarity.COMMON, mage.cards.b.Boomerang.class)); - cards.add(new SetCardInfo("Boris Devilboon", 223, Rarity.RARE, mage.cards.b.BorisDevilboon.class)); - cards.add(new SetCardInfo("Carrion Ants", 90, Rarity.RARE, mage.cards.c.CarrionAnts.class)); - cards.add(new SetCardInfo("Cat Warriors", 177, Rarity.COMMON, mage.cards.c.CatWarriors.class)); - cards.add(new SetCardInfo("Caverns of Despair", 136, Rarity.RARE, mage.cards.c.CavernsOfDespair.class)); - cards.add(new SetCardInfo("Chain Lightning", 137, Rarity.COMMON, mage.cards.c.ChainLightning.class)); - cards.add(new SetCardInfo("Chains of Mephistopheles", 91, Rarity.RARE, mage.cards.c.ChainsOfMephistopheles.class)); - cards.add(new SetCardInfo("Chromium", 224, Rarity.RARE, mage.cards.c.Chromium.class)); - cards.add(new SetCardInfo("Cleanse", 5, Rarity.RARE, mage.cards.c.Cleanse.class)); - cards.add(new SetCardInfo("Clergy of the Holy Nimbus", 6, Rarity.COMMON, mage.cards.c.ClergyOfTheHolyNimbus.class)); - cards.add(new SetCardInfo("Concordant Crossroads", 179, Rarity.RARE, mage.cards.c.ConcordantCrossroads.class)); - cards.add(new SetCardInfo("Cosmic Horror", 92, Rarity.RARE, mage.cards.c.CosmicHorror.class)); - cards.add(new SetCardInfo("Craw Giant", 180, Rarity.UNCOMMON, mage.cards.c.CrawGiant.class)); - cards.add(new SetCardInfo("Crevasse", 138, Rarity.UNCOMMON, mage.cards.c.Crevasse.class)); - cards.add(new SetCardInfo("Crimson Kobolds", 139, Rarity.COMMON, mage.cards.c.CrimsonKobolds.class)); - cards.add(new SetCardInfo("Crimson Manticore", 140, Rarity.RARE, mage.cards.c.CrimsonManticore.class)); - cards.add(new SetCardInfo("Crookshank Kobolds", 141, Rarity.COMMON, mage.cards.c.CrookshankKobolds.class)); - cards.add(new SetCardInfo("Cyclopean Mummy", 93, Rarity.COMMON, mage.cards.c.CyclopeanMummy.class)); - cards.add(new SetCardInfo("D'Avenant Archer", 7, Rarity.COMMON, mage.cards.d.DAvenantArcher.class)); - cards.add(new SetCardInfo("Dakkon Blackblade", 225, Rarity.RARE, mage.cards.d.DakkonBlackblade.class)); - cards.add(new SetCardInfo("Darkness", 94, Rarity.COMMON, mage.cards.d.Darkness.class)); - cards.add(new SetCardInfo("Deadfall", 181, Rarity.UNCOMMON, mage.cards.d.Deadfall.class)); - cards.add(new SetCardInfo("Demonic Torment", 95, Rarity.UNCOMMON, mage.cards.d.DemonicTorment.class)); - cards.add(new SetCardInfo("Devouring Deep", 50, Rarity.COMMON, mage.cards.d.DevouringDeep.class)); - cards.add(new SetCardInfo("Disharmony", 142, Rarity.RARE, mage.cards.d.Disharmony.class)); - cards.add(new SetCardInfo("Divine Intervention", 8, Rarity.RARE, mage.cards.d.DivineIntervention.class)); - cards.add(new SetCardInfo("Divine Offering", 9, Rarity.COMMON, mage.cards.d.DivineOffering.class)); - cards.add(new SetCardInfo("Divine Transformation", 10, Rarity.RARE, mage.cards.d.DivineTransformation.class)); - cards.add(new SetCardInfo("Dream Coat", 51, Rarity.UNCOMMON, mage.cards.d.DreamCoat.class)); - cards.add(new SetCardInfo("Durkwood Boars", 182, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); - cards.add(new SetCardInfo("Dwarven Song", 143, Rarity.UNCOMMON, mage.cards.d.DwarvenSong.class)); - cards.add(new SetCardInfo("Elder Land Wurm", 11, Rarity.RARE, mage.cards.e.ElderLandWurm.class)); - cards.add(new SetCardInfo("Elven Riders", 183, Rarity.RARE, mage.cards.e.ElvenRiders.class)); - cards.add(new SetCardInfo("Emerald Dragonfly", 184, Rarity.COMMON, mage.cards.e.EmeraldDragonfly.class)); - cards.add(new SetCardInfo("Energy Tap", 54, Rarity.COMMON, mage.cards.e.EnergyTap.class)); - cards.add(new SetCardInfo("Eternal Warrior", 144, Rarity.UNCOMMON, mage.cards.e.EternalWarrior.class)); - cards.add(new SetCardInfo("Eureka", 185, Rarity.RARE, mage.cards.e.Eureka.class)); - cards.add(new SetCardInfo("Evil Eye of Orms-by-Gore", 96, Rarity.UNCOMMON, mage.cards.e.EvilEyeOfOrmsByGore.class)); - cards.add(new SetCardInfo("Fallen Angel", 97, Rarity.UNCOMMON, mage.cards.f.FallenAngel.class)); - cards.add(new SetCardInfo("Field of Dreams", 55, Rarity.RARE, mage.cards.f.FieldOfDreams.class)); - cards.add(new SetCardInfo("Fire Sprites", 186, Rarity.COMMON, mage.cards.f.FireSprites.class)); - cards.add(new SetCardInfo("Flash Counter", 56, Rarity.COMMON, mage.cards.f.FlashCounter.class)); - cards.add(new SetCardInfo("Flash Flood", 57, Rarity.COMMON, mage.cards.f.FlashFlood.class)); - cards.add(new SetCardInfo("Floral Spuzzem", 187, Rarity.UNCOMMON, mage.cards.f.FloralSpuzzem.class)); - cards.add(new SetCardInfo("Force Spike", 58, Rarity.COMMON, mage.cards.f.ForceSpike.class)); - cards.add(new SetCardInfo("Fortified Area", 14, Rarity.UNCOMMON, mage.cards.f.FortifiedArea.class)); - cards.add(new SetCardInfo("Frost Giant", 148, Rarity.UNCOMMON, mage.cards.f.FrostGiant.class)); - cards.add(new SetCardInfo("Gabriel Angelfire", 226, Rarity.RARE, mage.cards.g.GabrielAngelfire.class)); - cards.add(new SetCardInfo("Gaseous Form", 59, Rarity.COMMON, mage.cards.g.GaseousForm.class)); - cards.add(new SetCardInfo("Gauntlets of Chaos", 278, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class)); - cards.add(new SetCardInfo("Ghosts of the Damned", 98, Rarity.COMMON, mage.cards.g.GhostsOfTheDamned.class)); - cards.add(new SetCardInfo("Giant Strength", 149, Rarity.COMMON, mage.cards.g.GiantStrength.class)); - cards.add(new SetCardInfo("Giant Turtle", 188, Rarity.COMMON, mage.cards.g.GiantTurtle.class)); - cards.add(new SetCardInfo("Glyph of Destruction", 150, Rarity.COMMON, mage.cards.g.GlyphOfDestruction.class)); - cards.add(new SetCardInfo("Glyph of Doom", 100, Rarity.COMMON, mage.cards.g.GlyphOfDoom.class)); - cards.add(new SetCardInfo("Glyph of Life", 15, Rarity.COMMON, mage.cards.g.GlyphOfLife.class)); - cards.add(new SetCardInfo("Gosta Dirk", 227, Rarity.RARE, mage.cards.g.GostaDirk.class)); - cards.add(new SetCardInfo("Gravity Sphere", 151, Rarity.RARE, mage.cards.g.GravitySphere.class)); - cards.add(new SetCardInfo("Great Defender", 16, Rarity.UNCOMMON, mage.cards.g.GreatDefender.class)); - cards.add(new SetCardInfo("Great Wall", 17, Rarity.UNCOMMON, mage.cards.g.GreatWall.class)); - cards.add(new SetCardInfo("Greater Realm of Preservation", 18, Rarity.UNCOMMON, mage.cards.g.GreaterRealmOfPreservation.class)); - cards.add(new SetCardInfo("Greed", 101, Rarity.RARE, mage.cards.g.Greed.class)); - cards.add(new SetCardInfo("Green Mana Battery", 279, Rarity.UNCOMMON, mage.cards.g.GreenManaBattery.class)); - cards.add(new SetCardInfo("Gwendlyn Di Corci", 228, Rarity.RARE, mage.cards.g.GwendlynDiCorci.class)); - cards.add(new SetCardInfo("Halfdane", 229, Rarity.RARE, mage.cards.h.Halfdane.class)); - cards.add(new SetCardInfo("Hammerheim", 302, Rarity.UNCOMMON, mage.cards.h.Hammerheim.class)); - cards.add(new SetCardInfo("Hazezon Tamar", 230, Rarity.RARE, mage.cards.h.HazezonTamar.class)); - cards.add(new SetCardInfo("Headless Horseman", 102, Rarity.COMMON, mage.cards.h.HeadlessHorseman.class)); - cards.add(new SetCardInfo("Heaven's Gate", 19, Rarity.UNCOMMON, mage.cards.h.HeavensGate.class)); - cards.add(new SetCardInfo("Hell Swarm", 103, Rarity.COMMON, mage.cards.h.HellSwarm.class)); - cards.add(new SetCardInfo("Hell's Caretaker", 104, Rarity.RARE, mage.cards.h.HellsCaretaker.class)); - cards.add(new SetCardInfo("Hellfire", 105, Rarity.RARE, mage.cards.h.Hellfire.class)); - cards.add(new SetCardInfo("Holy Day", 20, Rarity.COMMON, mage.cards.h.HolyDay.class)); - cards.add(new SetCardInfo("Horn of Deafening", 280, Rarity.RARE, mage.cards.h.HornOfDeafening.class)); - cards.add(new SetCardInfo("Hornet Cobra", 190, Rarity.COMMON, mage.cards.h.HornetCobra.class)); - cards.add(new SetCardInfo("Horror of Horrors", 106, Rarity.UNCOMMON, mage.cards.h.HorrorOfHorrors.class)); - cards.add(new SetCardInfo("Hunding Gjornersen", 231, Rarity.UNCOMMON, mage.cards.h.HundingGjornersen.class)); - cards.add(new SetCardInfo("Hyperion Blacksmith", 152, Rarity.UNCOMMON, mage.cards.h.HyperionBlacksmith.class)); - cards.add(new SetCardInfo("Immolation", 153, Rarity.COMMON, mage.cards.i.Immolation.class)); - cards.add(new SetCardInfo("Imprison", 107, Rarity.RARE, mage.cards.i.Imprison.class)); - cards.add(new SetCardInfo("In the Eye of Chaos", 61, Rarity.RARE, mage.cards.i.InTheEyeOfChaos.class)); - cards.add(new SetCardInfo("Indestructible Aura", 21, Rarity.COMMON, mage.cards.i.IndestructibleAura.class)); - cards.add(new SetCardInfo("Infernal Medusa", 108, Rarity.UNCOMMON, mage.cards.i.InfernalMedusa.class)); - cards.add(new SetCardInfo("Invoke Prejudice", 62, Rarity.RARE, mage.cards.i.InvokePrejudice.class)); - cards.add(new SetCardInfo("Ivory Guardians", 23, Rarity.UNCOMMON, mage.cards.i.IvoryGuardians.class)); - cards.add(new SetCardInfo("Jacques le Vert", 232, Rarity.RARE, mage.cards.j.JacquesLeVert.class)); - cards.add(new SetCardInfo("Jasmine Boreal", 233, Rarity.UNCOMMON, mage.cards.j.JasmineBoreal.class)); - cards.add(new SetCardInfo("Jedit Ojanen", 234, Rarity.UNCOMMON, mage.cards.j.JeditOjanen.class)); - cards.add(new SetCardInfo("Jerrard of the Closed Fist", 235, Rarity.UNCOMMON, mage.cards.j.JerrardOfTheClosedFist.class)); - cards.add(new SetCardInfo("Johan", 236, Rarity.RARE, mage.cards.j.Johan.class)); - cards.add(new SetCardInfo("Jovial Evil", 109, Rarity.RARE, mage.cards.j.JovialEvil.class)); - cards.add(new SetCardInfo("Juxtapose", 63, Rarity.RARE, mage.cards.j.Juxtapose.class)); - cards.add(new SetCardInfo("Karakas", 303, Rarity.UNCOMMON, mage.cards.k.Karakas.class)); - cards.add(new SetCardInfo("Kasimir the Lone Wolf", 237, Rarity.UNCOMMON, mage.cards.k.KasimirTheLoneWolf.class)); - cards.add(new SetCardInfo("Keepers of the Faith", 24, Rarity.COMMON, mage.cards.k.KeepersOfTheFaith.class)); - cards.add(new SetCardInfo("Kei Takahashi", 238, Rarity.RARE, mage.cards.k.KeiTakahashi.class)); - cards.add(new SetCardInfo("Killer Bees", 192, Rarity.RARE, mage.cards.k.KillerBees.class)); - cards.add(new SetCardInfo("Kismet", 25, Rarity.UNCOMMON, mage.cards.k.Kismet.class)); - cards.add(new SetCardInfo("Kobold Drill Sergeant", 154, Rarity.UNCOMMON, mage.cards.k.KoboldDrillSergeant.class)); - cards.add(new SetCardInfo("Kobold Overlord", 155, Rarity.RARE, mage.cards.k.KoboldOverlord.class)); - cards.add(new SetCardInfo("Kobold Taskmaster", 156, Rarity.UNCOMMON, mage.cards.k.KoboldTaskmaster.class)); - cards.add(new SetCardInfo("Kobolds of Kher Keep", 157, Rarity.COMMON, mage.cards.k.KoboldsOfKherKeep.class)); - cards.add(new SetCardInfo("Lady Caleria", 239, Rarity.RARE, mage.cards.l.LadyCaleria.class)); - cards.add(new SetCardInfo("Lady Evangela", 240, Rarity.RARE, mage.cards.l.LadyEvangela.class)); - cards.add(new SetCardInfo("Lady Orca", 241, Rarity.UNCOMMON, mage.cards.l.LadyOrca.class)); - cards.add(new SetCardInfo("Land Equilibrium", 64, Rarity.RARE, mage.cards.l.LandEquilibrium.class)); - cards.add(new SetCardInfo("Land Tax", 26, Rarity.UNCOMMON, mage.cards.l.LandTax.class)); - cards.add(new SetCardInfo("Land's Edge", 158, Rarity.RARE, mage.cards.l.LandsEdge.class)); - cards.add(new SetCardInfo("Life Chisel", 283, Rarity.UNCOMMON, mage.cards.l.LifeChisel.class)); - cards.add(new SetCardInfo("Lifeblood", 27, Rarity.RARE, mage.cards.l.Lifeblood.class)); - cards.add(new SetCardInfo("Living Plane", 193, Rarity.RARE, mage.cards.l.LivingPlane.class)); - cards.add(new SetCardInfo("Livonya Silone", 242, Rarity.RARE, mage.cards.l.LivonyaSilone.class)); - cards.add(new SetCardInfo("Lord Magnus", 243, Rarity.UNCOMMON, mage.cards.l.LordMagnus.class)); - cards.add(new SetCardInfo("Lost Soul", 111, Rarity.COMMON, mage.cards.l.LostSoul.class)); - cards.add(new SetCardInfo("Mana Drain", 65, Rarity.UNCOMMON, mage.cards.m.ManaDrain.class)); - cards.add(new SetCardInfo("Mana Matrix", 285, Rarity.RARE, mage.cards.m.ManaMatrix.class)); - cards.add(new SetCardInfo("Marble Priest", 286, Rarity.UNCOMMON, mage.cards.m.MarblePriest.class)); - cards.add(new SetCardInfo("Marhault Elsdragon", 244, Rarity.UNCOMMON, mage.cards.m.MarhaultElsdragon.class)); - cards.add(new SetCardInfo("Mirror Universe", 287, Rarity.RARE, mage.cards.m.MirrorUniverse.class)); - cards.add(new SetCardInfo("Moat", 28, Rarity.RARE, mage.cards.m.Moat.class)); - cards.add(new SetCardInfo("Mold Demon", 112, Rarity.RARE, mage.cards.m.MoldDemon.class)); - cards.add(new SetCardInfo("Moss Monster", 195, Rarity.COMMON, mage.cards.m.MossMonster.class)); - cards.add(new SetCardInfo("Mountain Yeti", 159, Rarity.UNCOMMON, mage.cards.m.MountainYeti.class)); - cards.add(new SetCardInfo("Nebuchadnezzar", 245, Rarity.RARE, mage.cards.n.Nebuchadnezzar.class)); - cards.add(new SetCardInfo("Nether Void", 113, Rarity.RARE, mage.cards.n.NetherVoid.class)); - cards.add(new SetCardInfo("Nicol Bolas", 246, Rarity.RARE, mage.cards.n.NicolBolas.class)); - cards.add(new SetCardInfo("Nova Pentacle", 289, Rarity.RARE, mage.cards.n.NovaPentacle.class)); - cards.add(new SetCardInfo("Osai Vultures", 29, Rarity.COMMON, mage.cards.o.OsaiVultures.class)); - cards.add(new SetCardInfo("Palladia-Mors", 247, Rarity.RARE, mage.cards.p.PalladiaMors.class)); - cards.add(new SetCardInfo("Part Water", 66, Rarity.UNCOMMON, mage.cards.p.PartWater.class)); - cards.add(new SetCardInfo("Pavel Maliki", 248, Rarity.UNCOMMON, mage.cards.p.PavelMaliki.class)); - cards.add(new SetCardInfo("Pendelhaven", 305, Rarity.UNCOMMON, mage.cards.p.Pendelhaven.class)); - cards.add(new SetCardInfo("Petra Sphinx", 30, Rarity.RARE, mage.cards.p.PetraSphinx.class)); - cards.add(new SetCardInfo("Pit Scorpion", 114, Rarity.COMMON, mage.cards.p.PitScorpion.class)); - cards.add(new SetCardInfo("Pixie Queen", 196, Rarity.RARE, mage.cards.p.PixieQueen.class)); - cards.add(new SetCardInfo("Planar Gate", 290, Rarity.RARE, mage.cards.p.PlanarGate.class)); - cards.add(new SetCardInfo("Pradesh Gypsies", 197, Rarity.UNCOMMON, mage.cards.p.PradeshGypsies.class)); - cards.add(new SetCardInfo("Presence of the Master", 31, Rarity.UNCOMMON, mage.cards.p.PresenceOfTheMaster.class)); - cards.add(new SetCardInfo("Primordial Ooze", 160, Rarity.UNCOMMON, mage.cards.p.PrimordialOoze.class)); - cards.add(new SetCardInfo("Princess Lucrezia", 249, Rarity.UNCOMMON, mage.cards.p.PrincessLucrezia.class)); - cards.add(new SetCardInfo("Psionic Entity", 67, Rarity.RARE, mage.cards.p.PsionicEntity.class)); - cards.add(new SetCardInfo("Psychic Purge", 68, Rarity.COMMON, mage.cards.p.PsychicPurge.class)); - cards.add(new SetCardInfo("Pyrotechnics", 161, Rarity.COMMON, mage.cards.p.Pyrotechnics.class)); - cards.add(new SetCardInfo("Quagmire", 115, Rarity.UNCOMMON, mage.cards.q.Quagmire.class)); - cards.add(new SetCardInfo("Rabid Wombat", 198, Rarity.UNCOMMON, mage.cards.r.RabidWombat.class)); - cards.add(new SetCardInfo("Radjan Spirit", 199, Rarity.UNCOMMON, mage.cards.r.RadjanSpirit.class)); - cards.add(new SetCardInfo("Raging Bull", 163, Rarity.COMMON, mage.cards.r.RagingBull.class)); - cards.add(new SetCardInfo("Ragnar", 250, Rarity.RARE, mage.cards.r.Ragnar.class)); - cards.add(new SetCardInfo("Ramirez DePietro", 251, Rarity.UNCOMMON, mage.cards.r.RamirezDePietro.class)); - cards.add(new SetCardInfo("Ramses Overdark", 252, Rarity.RARE, mage.cards.r.RamsesOverdark.class)); - cards.add(new SetCardInfo("Rasputin Dreamweaver", 253, Rarity.RARE, mage.cards.r.RasputinDreamweaver.class)); - cards.add(new SetCardInfo("Recall", 70, Rarity.RARE, mage.cards.r.Recall.class)); - cards.add(new SetCardInfo("Red Mana Battery", 291, Rarity.UNCOMMON, mage.cards.r.RedManaBattery.class)); - cards.add(new SetCardInfo("Reincarnation", 201, Rarity.UNCOMMON, mage.cards.r.Reincarnation.class)); - cards.add(new SetCardInfo("Relic Barrier", 292, Rarity.UNCOMMON, mage.cards.r.RelicBarrier.class)); - cards.add(new SetCardInfo("Relic Bind", 71, Rarity.UNCOMMON, mage.cards.r.RelicBind.class)); - cards.add(new SetCardInfo("Remove Enchantments", 33, Rarity.COMMON, mage.cards.r.RemoveEnchantments.class)); - cards.add(new SetCardInfo("Remove Soul", 72, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); - cards.add(new SetCardInfo("Reset", 73, Rarity.UNCOMMON, mage.cards.r.Reset.class)); - cards.add(new SetCardInfo("Revelation", 202, Rarity.RARE, mage.cards.r.Revelation.class)); - cards.add(new SetCardInfo("Righteous Avengers", 34, Rarity.UNCOMMON, mage.cards.r.RighteousAvengers.class)); - cards.add(new SetCardInfo("Ring of Immortals", 293, Rarity.RARE, mage.cards.r.RingOfImmortals.class)); - cards.add(new SetCardInfo("Riven Turnbull", 254, Rarity.UNCOMMON, mage.cards.r.RivenTurnbull.class)); - cards.add(new SetCardInfo("Rohgahh of Kher Keep", 255, Rarity.RARE, mage.cards.r.RohgahhOfKherKeep.class)); - cards.add(new SetCardInfo("Rubinia Soulsinger", 256, Rarity.RARE, mage.cards.r.RubiniaSoulsinger.class)); - cards.add(new SetCardInfo("Rust", 203, Rarity.COMMON, mage.cards.r.Rust.class)); - cards.add(new SetCardInfo("Sea Kings' Blessing", 75, Rarity.UNCOMMON, mage.cards.s.SeaKingsBlessing.class)); - cards.add(new SetCardInfo("Seeker", 35, Rarity.UNCOMMON, mage.cards.s.Seeker.class)); - cards.add(new SetCardInfo("Segovian Leviathan", 76, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); - cards.add(new SetCardInfo("Sentinel", 294, Rarity.RARE, mage.cards.s.Sentinel.class)); - cards.add(new SetCardInfo("Serpent Generator", 295, Rarity.RARE, mage.cards.s.SerpentGenerator.class)); - cards.add(new SetCardInfo("Shield Wall", 36, Rarity.UNCOMMON, mage.cards.s.ShieldWall.class)); - cards.add(new SetCardInfo("Shimian Night Stalker", 116, Rarity.UNCOMMON, mage.cards.s.ShimianNightStalker.class)); - cards.add(new SetCardInfo("Sir Shandlar of Eberyn", 257, Rarity.UNCOMMON, mage.cards.s.SirShandlarOfEberyn.class)); - cards.add(new SetCardInfo("Sivitri Scarzam", 258, Rarity.UNCOMMON, mage.cards.s.SivitriScarzam.class)); - cards.add(new SetCardInfo("Sol'kanar the Swamp King", 259, Rarity.RARE, mage.cards.s.SolkanarTheSwampKing.class)); - cards.add(new SetCardInfo("Spectral Cloak", 78, Rarity.UNCOMMON, mage.cards.s.SpectralCloak.class)); - cards.add(new SetCardInfo("Spinal Villain", 164, Rarity.RARE, mage.cards.s.SpinalVillain.class)); - cards.add(new SetCardInfo("Spirit Link", 37, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class)); - cards.add(new SetCardInfo("Spirit Shackle", 117, Rarity.COMMON, mage.cards.s.SpiritShackle.class)); - cards.add(new SetCardInfo("Spiritual Sanctuary", 38, Rarity.RARE, mage.cards.s.SpiritualSanctuary.class)); - cards.add(new SetCardInfo("Stangg", 260, Rarity.RARE, mage.cards.s.Stangg.class)); - cards.add(new SetCardInfo("Storm Seeker", 205, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class)); - cards.add(new SetCardInfo("Storm World", 165, Rarity.RARE, mage.cards.s.StormWorld.class)); - cards.add(new SetCardInfo("Sunastian Falconer", 261, Rarity.UNCOMMON, mage.cards.s.SunastianFalconer.class)); - cards.add(new SetCardInfo("Sword of the Ages", 296, Rarity.RARE, mage.cards.s.SwordOfTheAges.class)); - cards.add(new SetCardInfo("Sylvan Library", 207, Rarity.UNCOMMON, mage.cards.s.SylvanLibrary.class)); - cards.add(new SetCardInfo("Sylvan Paradise", 208, Rarity.UNCOMMON, mage.cards.s.SylvanParadise.class)); - cards.add(new SetCardInfo("Syphon Soul", 118, Rarity.COMMON, mage.cards.s.SyphonSoul.class)); - cards.add(new SetCardInfo("Telekinesis", 79, Rarity.RARE, mage.cards.t.Telekinesis.class)); - cards.add(new SetCardInfo("Teleport", 80, Rarity.RARE, mage.cards.t.Teleport.class)); - cards.add(new SetCardInfo("Tetsuo Umezawa", 262, Rarity.RARE, mage.cards.t.TetsuoUmezawa.class)); - cards.add(new SetCardInfo("The Abyss", 120, Rarity.RARE, mage.cards.t.TheAbyss.class)); - cards.add(new SetCardInfo("The Brute", 167, Rarity.COMMON, mage.cards.t.TheBrute.class)); - cards.add(new SetCardInfo("The Lady of the Mountain", 263, Rarity.UNCOMMON, mage.cards.t.TheLadyOfTheMountain.class)); - cards.add(new SetCardInfo("The Tabernacle at Pendrell Vale", 307, Rarity.RARE, mage.cards.t.TheTabernacleAtPendrellVale.class)); - cards.add(new SetCardInfo("The Wretched", 121, Rarity.RARE, mage.cards.t.TheWretched.class)); - cards.add(new SetCardInfo("Thunder Spirit", 39, Rarity.RARE, mage.cards.t.ThunderSpirit.class)); - cards.add(new SetCardInfo("Time Elemental", 81, Rarity.RARE, mage.cards.t.TimeElemental.class)); - cards.add(new SetCardInfo("Tobias Andrion", 264, Rarity.UNCOMMON, mage.cards.t.TobiasAndrion.class)); - cards.add(new SetCardInfo("Tor Wauki", 265, Rarity.UNCOMMON, mage.cards.t.TorWauki.class)); - cards.add(new SetCardInfo("Torsten Von Ursus", 266, Rarity.UNCOMMON, mage.cards.t.TorstenVonUrsus.class)); - cards.add(new SetCardInfo("Touch of Darkness", 122, Rarity.UNCOMMON, mage.cards.t.TouchOfDarkness.class)); - cards.add(new SetCardInfo("Transmutation", 123, Rarity.COMMON, mage.cards.t.Transmutation.class)); - cards.add(new SetCardInfo("Triassic Egg", 297, Rarity.RARE, mage.cards.t.TriassicEgg.class)); - cards.add(new SetCardInfo("Tuknir Deathlock", 267, Rarity.RARE, mage.cards.t.TuknirDeathlock.class)); - cards.add(new SetCardInfo("Tundra Wolves", 40, Rarity.COMMON, mage.cards.t.TundraWolves.class)); - cards.add(new SetCardInfo("Typhoon", 209, Rarity.RARE, mage.cards.t.Typhoon.class)); - cards.add(new SetCardInfo("Undertow", 82, Rarity.UNCOMMON, mage.cards.u.Undertow.class)); - cards.add(new SetCardInfo("Underworld Dreams", 124, Rarity.UNCOMMON, mage.cards.u.UnderworldDreams.class)); - cards.add(new SetCardInfo("Untamed Wilds", 210, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); - cards.add(new SetCardInfo("Ur-Drago", 268, Rarity.RARE, mage.cards.u.UrDrago.class)); - cards.add(new SetCardInfo("Urborg", 310, Rarity.UNCOMMON, mage.cards.u.Urborg.class)); - cards.add(new SetCardInfo("Vaevictis Asmadi", 269, Rarity.RARE, mage.cards.v.VaevictisAsmadi.class)); - cards.add(new SetCardInfo("Vampire Bats", 125, Rarity.COMMON, mage.cards.v.VampireBats.class)); - cards.add(new SetCardInfo("Visions", 41, Rarity.UNCOMMON, mage.cards.v.Visions.class)); - cards.add(new SetCardInfo("Walking Dead", 126, Rarity.COMMON, mage.cards.w.WalkingDead.class)); - cards.add(new SetCardInfo("Wall of Caltrops", 42, Rarity.COMMON, mage.cards.w.WallOfCaltrops.class)); - cards.add(new SetCardInfo("Wall of Dust", 168, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class)); - cards.add(new SetCardInfo("Wall of Earth", 169, Rarity.COMMON, mage.cards.w.WallOfEarth.class)); - cards.add(new SetCardInfo("Wall of Heat", 170, Rarity.COMMON, mage.cards.w.WallOfHeat.class)); - cards.add(new SetCardInfo("Wall of Light", 43, Rarity.UNCOMMON, mage.cards.w.WallOfLight.class)); - cards.add(new SetCardInfo("Wall of Opposition", 171, Rarity.RARE, mage.cards.w.WallOfOpposition.class)); - cards.add(new SetCardInfo("Wall of Putrid Flesh", 127, Rarity.UNCOMMON, mage.cards.w.WallOfPutridFlesh.class)); - cards.add(new SetCardInfo("Wall of Vapor", 84, Rarity.COMMON, mage.cards.w.WallOfVapor.class)); - cards.add(new SetCardInfo("Wall of Wonder", 85, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class)); - cards.add(new SetCardInfo("Whirling Dervish", 211, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class)); - cards.add(new SetCardInfo("White Mana Battery", 299, Rarity.UNCOMMON, mage.cards.w.WhiteManaBattery.class)); - cards.add(new SetCardInfo("Willow Satyr", 212, Rarity.RARE, mage.cards.w.WillowSatyr.class)); - cards.add(new SetCardInfo("Winds of Change", 172, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class)); - cards.add(new SetCardInfo("Winter Blast", 213, Rarity.RARE, mage.cards.w.WinterBlast.class)); - cards.add(new SetCardInfo("Wolverine Pack", 214, Rarity.COMMON, mage.cards.w.WolverinePack.class)); - cards.add(new SetCardInfo("Wood Elemental", 215, Rarity.RARE, mage.cards.w.WoodElemental.class)); - cards.add(new SetCardInfo("Xira Arien", 270, Rarity.RARE, mage.cards.x.XiraArien.class)); - cards.add(new SetCardInfo("Zephyr Falcon", 86, Rarity.COMMON, mage.cards.z.ZephyrFalcon.class)); - } -} +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author North + */ +public final class Legends extends ExpansionSet { + + private static final Legends instance = new Legends(); + + public static Legends getInstance() { + return instance; + } + + private Legends() { + super("Legends", "LEG", ExpansionSet.buildDate(1994, 6, 1), SetType.EXPANSION); + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abomination", 87, Rarity.UNCOMMON, mage.cards.a.Abomination.class)); + cards.add(new SetCardInfo("Acid Rain", 44, Rarity.RARE, mage.cards.a.AcidRain.class)); + cards.add(new SetCardInfo("Active Volcano", 130, Rarity.COMMON, mage.cards.a.ActiveVolcano.class)); + cards.add(new SetCardInfo("Adun Oakenshield", 216, Rarity.RARE, mage.cards.a.AdunOakenshield.class)); + cards.add(new SetCardInfo("Aerathi Berserker", 131, Rarity.UNCOMMON, mage.cards.a.AerathiBerserker.class)); + cards.add(new SetCardInfo("Aisling Leprechaun", 173, Rarity.COMMON, mage.cards.a.AislingLeprechaun.class)); + cards.add(new SetCardInfo("Akron Legionnaire", 1, Rarity.RARE, mage.cards.a.AkronLegionnaire.class)); + cards.add(new SetCardInfo("Al-abara's Carpet", 271, Rarity.RARE, mage.cards.a.AlAbarasCarpet.class)); + cards.add(new SetCardInfo("Alabaster Potion", 2, Rarity.COMMON, mage.cards.a.AlabasterPotion.class)); + cards.add(new SetCardInfo("Alchor's Tomb", 272, Rarity.RARE, mage.cards.a.AlchorsTomb.class)); + cards.add(new SetCardInfo("All Hallow's Eve", 88, Rarity.RARE, mage.cards.a.AllHallowsEve.class)); + cards.add(new SetCardInfo("Amrou Kithkin", 3, Rarity.COMMON, mage.cards.a.AmrouKithkin.class)); + cards.add(new SetCardInfo("Angelic Voices", 4, Rarity.RARE, mage.cards.a.AngelicVoices.class)); + cards.add(new SetCardInfo("Angus Mackenzie", 217, Rarity.RARE, mage.cards.a.AngusMackenzie.class)); + cards.add(new SetCardInfo("Anti-Magic Aura", 45, Rarity.COMMON, mage.cards.a.AntiMagicAura.class)); + cards.add(new SetCardInfo("Arboria", 174, Rarity.UNCOMMON, mage.cards.a.Arboria.class)); + cards.add(new SetCardInfo("Arcades Sabboth", 218, Rarity.RARE, mage.cards.a.ArcadesSabboth.class)); + cards.add(new SetCardInfo("Arena of the Ancients", 273, Rarity.RARE, mage.cards.a.ArenaOfTheAncients.class)); + cards.add(new SetCardInfo("Avoid Fate", 175, Rarity.COMMON, mage.cards.a.AvoidFate.class)); + cards.add(new SetCardInfo("Axelrod Gunnarson", 219, Rarity.RARE, mage.cards.a.AxelrodGunnarson.class)); + cards.add(new SetCardInfo("Ayesha Tanaka", 220, Rarity.RARE, mage.cards.a.AyeshaTanaka.class)); + cards.add(new SetCardInfo("Azure Drake", 46, Rarity.UNCOMMON, mage.cards.a.AzureDrake.class)); + cards.add(new SetCardInfo("Backfire", 47, Rarity.UNCOMMON, mage.cards.b.Backfire.class)); + cards.add(new SetCardInfo("Barbary Apes", 176, Rarity.COMMON, mage.cards.b.BarbaryApes.class)); + cards.add(new SetCardInfo("Barktooth Warbeard", 221, Rarity.UNCOMMON, mage.cards.b.BarktoothWarbeard.class)); + cards.add(new SetCardInfo("Bartel Runeaxe", 222, Rarity.RARE, mage.cards.b.BartelRuneaxe.class)); + cards.add(new SetCardInfo("Beasts of Bogardan", 133, Rarity.UNCOMMON, mage.cards.b.BeastsOfBogardan.class)); + cards.add(new SetCardInfo("Black Mana Battery", 274, Rarity.UNCOMMON, mage.cards.b.BlackManaBattery.class)); + cards.add(new SetCardInfo("Blight", 89, Rarity.UNCOMMON, mage.cards.b.Blight.class)); + cards.add(new SetCardInfo("Blood Lust", 135, Rarity.UNCOMMON, mage.cards.b.BloodLust.class)); + cards.add(new SetCardInfo("Blue Mana Battery", 275, Rarity.UNCOMMON, mage.cards.b.BlueManaBattery.class)); + cards.add(new SetCardInfo("Boomerang", 48, Rarity.COMMON, mage.cards.b.Boomerang.class)); + cards.add(new SetCardInfo("Boris Devilboon", 223, Rarity.RARE, mage.cards.b.BorisDevilboon.class)); + cards.add(new SetCardInfo("Carrion Ants", 90, Rarity.RARE, mage.cards.c.CarrionAnts.class)); + cards.add(new SetCardInfo("Cat Warriors", 177, Rarity.COMMON, mage.cards.c.CatWarriors.class)); + cards.add(new SetCardInfo("Caverns of Despair", 136, Rarity.RARE, mage.cards.c.CavernsOfDespair.class)); + cards.add(new SetCardInfo("Chain Lightning", 137, Rarity.COMMON, mage.cards.c.ChainLightning.class)); + cards.add(new SetCardInfo("Chains of Mephistopheles", 91, Rarity.RARE, mage.cards.c.ChainsOfMephistopheles.class)); + cards.add(new SetCardInfo("Chromium", 224, Rarity.RARE, mage.cards.c.Chromium.class)); + cards.add(new SetCardInfo("Cleanse", 5, Rarity.RARE, mage.cards.c.Cleanse.class)); + cards.add(new SetCardInfo("Clergy of the Holy Nimbus", 6, Rarity.COMMON, mage.cards.c.ClergyOfTheHolyNimbus.class)); + cards.add(new SetCardInfo("Concordant Crossroads", 179, Rarity.RARE, mage.cards.c.ConcordantCrossroads.class)); + cards.add(new SetCardInfo("Cosmic Horror", 92, Rarity.RARE, mage.cards.c.CosmicHorror.class)); + cards.add(new SetCardInfo("Craw Giant", 180, Rarity.UNCOMMON, mage.cards.c.CrawGiant.class)); + cards.add(new SetCardInfo("Crevasse", 138, Rarity.UNCOMMON, mage.cards.c.Crevasse.class)); + cards.add(new SetCardInfo("Crimson Kobolds", 139, Rarity.COMMON, mage.cards.c.CrimsonKobolds.class)); + cards.add(new SetCardInfo("Crimson Manticore", 140, Rarity.RARE, mage.cards.c.CrimsonManticore.class)); + cards.add(new SetCardInfo("Crookshank Kobolds", 141, Rarity.COMMON, mage.cards.c.CrookshankKobolds.class)); + cards.add(new SetCardInfo("Cyclopean Mummy", 93, Rarity.COMMON, mage.cards.c.CyclopeanMummy.class)); + cards.add(new SetCardInfo("D'Avenant Archer", 7, Rarity.COMMON, mage.cards.d.DAvenantArcher.class)); + cards.add(new SetCardInfo("Dakkon Blackblade", 225, Rarity.RARE, mage.cards.d.DakkonBlackblade.class)); + cards.add(new SetCardInfo("Darkness", 94, Rarity.COMMON, mage.cards.d.Darkness.class)); + cards.add(new SetCardInfo("Deadfall", 181, Rarity.UNCOMMON, mage.cards.d.Deadfall.class)); + cards.add(new SetCardInfo("Demonic Torment", 95, Rarity.UNCOMMON, mage.cards.d.DemonicTorment.class)); + cards.add(new SetCardInfo("Devouring Deep", 50, Rarity.COMMON, mage.cards.d.DevouringDeep.class)); + cards.add(new SetCardInfo("Disharmony", 142, Rarity.RARE, mage.cards.d.Disharmony.class)); + cards.add(new SetCardInfo("Divine Intervention", 8, Rarity.RARE, mage.cards.d.DivineIntervention.class)); + cards.add(new SetCardInfo("Divine Offering", 9, Rarity.COMMON, mage.cards.d.DivineOffering.class)); + cards.add(new SetCardInfo("Divine Transformation", 10, Rarity.RARE, mage.cards.d.DivineTransformation.class)); + cards.add(new SetCardInfo("Dream Coat", 51, Rarity.UNCOMMON, mage.cards.d.DreamCoat.class)); + cards.add(new SetCardInfo("Durkwood Boars", 182, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); + cards.add(new SetCardInfo("Dwarven Song", 143, Rarity.UNCOMMON, mage.cards.d.DwarvenSong.class)); + cards.add(new SetCardInfo("Elder Land Wurm", 11, Rarity.RARE, mage.cards.e.ElderLandWurm.class)); + cards.add(new SetCardInfo("Elven Riders", 183, Rarity.RARE, mage.cards.e.ElvenRiders.class)); + cards.add(new SetCardInfo("Emerald Dragonfly", 184, Rarity.COMMON, mage.cards.e.EmeraldDragonfly.class)); + cards.add(new SetCardInfo("Enchantment Alteration", 53, Rarity.COMMON, mage.cards.e.EnchantmentAlteration.class)); + cards.add(new SetCardInfo("Energy Tap", 54, Rarity.COMMON, mage.cards.e.EnergyTap.class)); + cards.add(new SetCardInfo("Eternal Warrior", 144, Rarity.UNCOMMON, mage.cards.e.EternalWarrior.class)); + cards.add(new SetCardInfo("Eureka", 185, Rarity.RARE, mage.cards.e.Eureka.class)); + cards.add(new SetCardInfo("Evil Eye of Orms-by-Gore", 96, Rarity.UNCOMMON, mage.cards.e.EvilEyeOfOrmsByGore.class)); + cards.add(new SetCardInfo("Fallen Angel", 97, Rarity.UNCOMMON, mage.cards.f.FallenAngel.class)); + cards.add(new SetCardInfo("Field of Dreams", 55, Rarity.RARE, mage.cards.f.FieldOfDreams.class)); + cards.add(new SetCardInfo("Fire Sprites", 186, Rarity.COMMON, mage.cards.f.FireSprites.class)); + cards.add(new SetCardInfo("Flash Counter", 56, Rarity.COMMON, mage.cards.f.FlashCounter.class)); + cards.add(new SetCardInfo("Flash Flood", 57, Rarity.COMMON, mage.cards.f.FlashFlood.class)); + cards.add(new SetCardInfo("Floral Spuzzem", 187, Rarity.UNCOMMON, mage.cards.f.FloralSpuzzem.class)); + cards.add(new SetCardInfo("Force Spike", 58, Rarity.COMMON, mage.cards.f.ForceSpike.class)); + cards.add(new SetCardInfo("Fortified Area", 14, Rarity.UNCOMMON, mage.cards.f.FortifiedArea.class)); + cards.add(new SetCardInfo("Frost Giant", 148, Rarity.UNCOMMON, mage.cards.f.FrostGiant.class)); + cards.add(new SetCardInfo("Gabriel Angelfire", 226, Rarity.RARE, mage.cards.g.GabrielAngelfire.class)); + cards.add(new SetCardInfo("Gaseous Form", 59, Rarity.COMMON, mage.cards.g.GaseousForm.class)); + cards.add(new SetCardInfo("Gauntlets of Chaos", 278, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class)); + cards.add(new SetCardInfo("Ghosts of the Damned", 98, Rarity.COMMON, mage.cards.g.GhostsOfTheDamned.class)); + cards.add(new SetCardInfo("Giant Strength", 149, Rarity.COMMON, mage.cards.g.GiantStrength.class)); + cards.add(new SetCardInfo("Giant Turtle", 188, Rarity.COMMON, mage.cards.g.GiantTurtle.class)); + cards.add(new SetCardInfo("Glyph of Destruction", 150, Rarity.COMMON, mage.cards.g.GlyphOfDestruction.class)); + cards.add(new SetCardInfo("Glyph of Doom", 100, Rarity.COMMON, mage.cards.g.GlyphOfDoom.class)); + cards.add(new SetCardInfo("Glyph of Life", 15, Rarity.COMMON, mage.cards.g.GlyphOfLife.class)); + cards.add(new SetCardInfo("Gosta Dirk", 227, Rarity.RARE, mage.cards.g.GostaDirk.class)); + cards.add(new SetCardInfo("Gravity Sphere", 151, Rarity.RARE, mage.cards.g.GravitySphere.class)); + cards.add(new SetCardInfo("Great Defender", 16, Rarity.UNCOMMON, mage.cards.g.GreatDefender.class)); + cards.add(new SetCardInfo("Great Wall", 17, Rarity.UNCOMMON, mage.cards.g.GreatWall.class)); + cards.add(new SetCardInfo("Greater Realm of Preservation", 18, Rarity.UNCOMMON, mage.cards.g.GreaterRealmOfPreservation.class)); + cards.add(new SetCardInfo("Greed", 101, Rarity.RARE, mage.cards.g.Greed.class)); + cards.add(new SetCardInfo("Green Mana Battery", 279, Rarity.UNCOMMON, mage.cards.g.GreenManaBattery.class)); + cards.add(new SetCardInfo("Gwendlyn Di Corci", 228, Rarity.RARE, mage.cards.g.GwendlynDiCorci.class)); + cards.add(new SetCardInfo("Halfdane", 229, Rarity.RARE, mage.cards.h.Halfdane.class)); + cards.add(new SetCardInfo("Hammerheim", 302, Rarity.UNCOMMON, mage.cards.h.Hammerheim.class)); + cards.add(new SetCardInfo("Hazezon Tamar", 230, Rarity.RARE, mage.cards.h.HazezonTamar.class)); + cards.add(new SetCardInfo("Headless Horseman", 102, Rarity.COMMON, mage.cards.h.HeadlessHorseman.class)); + cards.add(new SetCardInfo("Heaven's Gate", 19, Rarity.UNCOMMON, mage.cards.h.HeavensGate.class)); + cards.add(new SetCardInfo("Hell Swarm", 103, Rarity.COMMON, mage.cards.h.HellSwarm.class)); + cards.add(new SetCardInfo("Hell's Caretaker", 104, Rarity.RARE, mage.cards.h.HellsCaretaker.class)); + cards.add(new SetCardInfo("Hellfire", 105, Rarity.RARE, mage.cards.h.Hellfire.class)); + cards.add(new SetCardInfo("Holy Day", 20, Rarity.COMMON, mage.cards.h.HolyDay.class)); + cards.add(new SetCardInfo("Horn of Deafening", 280, Rarity.RARE, mage.cards.h.HornOfDeafening.class)); + cards.add(new SetCardInfo("Hornet Cobra", 190, Rarity.COMMON, mage.cards.h.HornetCobra.class)); + cards.add(new SetCardInfo("Horror of Horrors", 106, Rarity.UNCOMMON, mage.cards.h.HorrorOfHorrors.class)); + cards.add(new SetCardInfo("Hunding Gjornersen", 231, Rarity.UNCOMMON, mage.cards.h.HundingGjornersen.class)); + cards.add(new SetCardInfo("Hyperion Blacksmith", 152, Rarity.UNCOMMON, mage.cards.h.HyperionBlacksmith.class)); + cards.add(new SetCardInfo("Immolation", 153, Rarity.COMMON, mage.cards.i.Immolation.class)); + cards.add(new SetCardInfo("Imprison", 107, Rarity.RARE, mage.cards.i.Imprison.class)); + cards.add(new SetCardInfo("In the Eye of Chaos", 61, Rarity.RARE, mage.cards.i.InTheEyeOfChaos.class)); + cards.add(new SetCardInfo("Indestructible Aura", 21, Rarity.COMMON, mage.cards.i.IndestructibleAura.class)); + cards.add(new SetCardInfo("Infernal Medusa", 108, Rarity.UNCOMMON, mage.cards.i.InfernalMedusa.class)); + cards.add(new SetCardInfo("Invoke Prejudice", 62, Rarity.RARE, mage.cards.i.InvokePrejudice.class)); + cards.add(new SetCardInfo("Ivory Guardians", 23, Rarity.UNCOMMON, mage.cards.i.IvoryGuardians.class)); + cards.add(new SetCardInfo("Jacques le Vert", 232, Rarity.RARE, mage.cards.j.JacquesLeVert.class)); + cards.add(new SetCardInfo("Jasmine Boreal", 233, Rarity.UNCOMMON, mage.cards.j.JasmineBoreal.class)); + cards.add(new SetCardInfo("Jedit Ojanen", 234, Rarity.UNCOMMON, mage.cards.j.JeditOjanen.class)); + cards.add(new SetCardInfo("Jerrard of the Closed Fist", 235, Rarity.UNCOMMON, mage.cards.j.JerrardOfTheClosedFist.class)); + cards.add(new SetCardInfo("Johan", 236, Rarity.RARE, mage.cards.j.Johan.class)); + cards.add(new SetCardInfo("Jovial Evil", 109, Rarity.RARE, mage.cards.j.JovialEvil.class)); + cards.add(new SetCardInfo("Juxtapose", 63, Rarity.RARE, mage.cards.j.Juxtapose.class)); + cards.add(new SetCardInfo("Karakas", 303, Rarity.UNCOMMON, mage.cards.k.Karakas.class)); + cards.add(new SetCardInfo("Kasimir the Lone Wolf", 237, Rarity.UNCOMMON, mage.cards.k.KasimirTheLoneWolf.class)); + cards.add(new SetCardInfo("Keepers of the Faith", 24, Rarity.COMMON, mage.cards.k.KeepersOfTheFaith.class)); + cards.add(new SetCardInfo("Kei Takahashi", 238, Rarity.RARE, mage.cards.k.KeiTakahashi.class)); + cards.add(new SetCardInfo("Killer Bees", 192, Rarity.RARE, mage.cards.k.KillerBees.class)); + cards.add(new SetCardInfo("Kismet", 25, Rarity.UNCOMMON, mage.cards.k.Kismet.class)); + cards.add(new SetCardInfo("Kobold Drill Sergeant", 154, Rarity.UNCOMMON, mage.cards.k.KoboldDrillSergeant.class)); + cards.add(new SetCardInfo("Kobold Overlord", 155, Rarity.RARE, mage.cards.k.KoboldOverlord.class)); + cards.add(new SetCardInfo("Kobold Taskmaster", 156, Rarity.UNCOMMON, mage.cards.k.KoboldTaskmaster.class)); + cards.add(new SetCardInfo("Kobolds of Kher Keep", 157, Rarity.COMMON, mage.cards.k.KoboldsOfKherKeep.class)); + cards.add(new SetCardInfo("Lady Caleria", 239, Rarity.RARE, mage.cards.l.LadyCaleria.class)); + cards.add(new SetCardInfo("Lady Evangela", 240, Rarity.RARE, mage.cards.l.LadyEvangela.class)); + cards.add(new SetCardInfo("Lady Orca", 241, Rarity.UNCOMMON, mage.cards.l.LadyOrca.class)); + cards.add(new SetCardInfo("Land Equilibrium", 64, Rarity.RARE, mage.cards.l.LandEquilibrium.class)); + cards.add(new SetCardInfo("Land Tax", 26, Rarity.UNCOMMON, mage.cards.l.LandTax.class)); + cards.add(new SetCardInfo("Land's Edge", 158, Rarity.RARE, mage.cards.l.LandsEdge.class)); + cards.add(new SetCardInfo("Life Chisel", 283, Rarity.UNCOMMON, mage.cards.l.LifeChisel.class)); + cards.add(new SetCardInfo("Lifeblood", 27, Rarity.RARE, mage.cards.l.Lifeblood.class)); + cards.add(new SetCardInfo("Living Plane", 193, Rarity.RARE, mage.cards.l.LivingPlane.class)); + cards.add(new SetCardInfo("Livonya Silone", 242, Rarity.RARE, mage.cards.l.LivonyaSilone.class)); + cards.add(new SetCardInfo("Lord Magnus", 243, Rarity.UNCOMMON, mage.cards.l.LordMagnus.class)); + cards.add(new SetCardInfo("Lost Soul", 111, Rarity.COMMON, mage.cards.l.LostSoul.class)); + cards.add(new SetCardInfo("Mana Drain", 65, Rarity.UNCOMMON, mage.cards.m.ManaDrain.class)); + cards.add(new SetCardInfo("Mana Matrix", 285, Rarity.RARE, mage.cards.m.ManaMatrix.class)); + cards.add(new SetCardInfo("Marble Priest", 286, Rarity.UNCOMMON, mage.cards.m.MarblePriest.class)); + cards.add(new SetCardInfo("Marhault Elsdragon", 244, Rarity.UNCOMMON, mage.cards.m.MarhaultElsdragon.class)); + cards.add(new SetCardInfo("Mirror Universe", 287, Rarity.RARE, mage.cards.m.MirrorUniverse.class)); + cards.add(new SetCardInfo("Moat", 28, Rarity.RARE, mage.cards.m.Moat.class)); + cards.add(new SetCardInfo("Mold Demon", 112, Rarity.RARE, mage.cards.m.MoldDemon.class)); + cards.add(new SetCardInfo("Moss Monster", 195, Rarity.COMMON, mage.cards.m.MossMonster.class)); + cards.add(new SetCardInfo("Mountain Yeti", 159, Rarity.UNCOMMON, mage.cards.m.MountainYeti.class)); + cards.add(new SetCardInfo("Nebuchadnezzar", 245, Rarity.RARE, mage.cards.n.Nebuchadnezzar.class)); + cards.add(new SetCardInfo("Nether Void", 113, Rarity.RARE, mage.cards.n.NetherVoid.class)); + cards.add(new SetCardInfo("Nicol Bolas", 246, Rarity.RARE, mage.cards.n.NicolBolas.class)); + cards.add(new SetCardInfo("Nova Pentacle", 289, Rarity.RARE, mage.cards.n.NovaPentacle.class)); + cards.add(new SetCardInfo("Osai Vultures", 29, Rarity.COMMON, mage.cards.o.OsaiVultures.class)); + cards.add(new SetCardInfo("Palladia-Mors", 247, Rarity.RARE, mage.cards.p.PalladiaMors.class)); + cards.add(new SetCardInfo("Part Water", 66, Rarity.UNCOMMON, mage.cards.p.PartWater.class)); + cards.add(new SetCardInfo("Pavel Maliki", 248, Rarity.UNCOMMON, mage.cards.p.PavelMaliki.class)); + cards.add(new SetCardInfo("Pendelhaven", 305, Rarity.UNCOMMON, mage.cards.p.Pendelhaven.class)); + cards.add(new SetCardInfo("Petra Sphinx", 30, Rarity.RARE, mage.cards.p.PetraSphinx.class)); + cards.add(new SetCardInfo("Pit Scorpion", 114, Rarity.COMMON, mage.cards.p.PitScorpion.class)); + cards.add(new SetCardInfo("Pixie Queen", 196, Rarity.RARE, mage.cards.p.PixieQueen.class)); + cards.add(new SetCardInfo("Planar Gate", 290, Rarity.RARE, mage.cards.p.PlanarGate.class)); + cards.add(new SetCardInfo("Pradesh Gypsies", 197, Rarity.UNCOMMON, mage.cards.p.PradeshGypsies.class)); + cards.add(new SetCardInfo("Presence of the Master", 31, Rarity.UNCOMMON, mage.cards.p.PresenceOfTheMaster.class)); + cards.add(new SetCardInfo("Primordial Ooze", 160, Rarity.UNCOMMON, mage.cards.p.PrimordialOoze.class)); + cards.add(new SetCardInfo("Princess Lucrezia", 249, Rarity.UNCOMMON, mage.cards.p.PrincessLucrezia.class)); + cards.add(new SetCardInfo("Psionic Entity", 67, Rarity.RARE, mage.cards.p.PsionicEntity.class)); + cards.add(new SetCardInfo("Psychic Purge", 68, Rarity.COMMON, mage.cards.p.PsychicPurge.class)); + cards.add(new SetCardInfo("Pyrotechnics", 161, Rarity.COMMON, mage.cards.p.Pyrotechnics.class)); + cards.add(new SetCardInfo("Quagmire", 115, Rarity.UNCOMMON, mage.cards.q.Quagmire.class)); + cards.add(new SetCardInfo("Rabid Wombat", 198, Rarity.UNCOMMON, mage.cards.r.RabidWombat.class)); + cards.add(new SetCardInfo("Radjan Spirit", 199, Rarity.UNCOMMON, mage.cards.r.RadjanSpirit.class)); + cards.add(new SetCardInfo("Raging Bull", 163, Rarity.COMMON, mage.cards.r.RagingBull.class)); + cards.add(new SetCardInfo("Ragnar", 250, Rarity.RARE, mage.cards.r.Ragnar.class)); + cards.add(new SetCardInfo("Ramirez DePietro", 251, Rarity.UNCOMMON, mage.cards.r.RamirezDePietro.class)); + cards.add(new SetCardInfo("Ramses Overdark", 252, Rarity.RARE, mage.cards.r.RamsesOverdark.class)); + cards.add(new SetCardInfo("Rasputin Dreamweaver", 253, Rarity.RARE, mage.cards.r.RasputinDreamweaver.class)); + cards.add(new SetCardInfo("Recall", 70, Rarity.RARE, mage.cards.r.Recall.class)); + cards.add(new SetCardInfo("Red Mana Battery", 291, Rarity.UNCOMMON, mage.cards.r.RedManaBattery.class)); + cards.add(new SetCardInfo("Reincarnation", 201, Rarity.UNCOMMON, mage.cards.r.Reincarnation.class)); + cards.add(new SetCardInfo("Relic Barrier", 292, Rarity.UNCOMMON, mage.cards.r.RelicBarrier.class)); + cards.add(new SetCardInfo("Relic Bind", 71, Rarity.UNCOMMON, mage.cards.r.RelicBind.class)); + cards.add(new SetCardInfo("Remove Enchantments", 33, Rarity.COMMON, mage.cards.r.RemoveEnchantments.class)); + cards.add(new SetCardInfo("Remove Soul", 72, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); + cards.add(new SetCardInfo("Reset", 73, Rarity.UNCOMMON, mage.cards.r.Reset.class)); + cards.add(new SetCardInfo("Revelation", 202, Rarity.RARE, mage.cards.r.Revelation.class)); + cards.add(new SetCardInfo("Righteous Avengers", 34, Rarity.UNCOMMON, mage.cards.r.RighteousAvengers.class)); + cards.add(new SetCardInfo("Ring of Immortals", 293, Rarity.RARE, mage.cards.r.RingOfImmortals.class)); + cards.add(new SetCardInfo("Riven Turnbull", 254, Rarity.UNCOMMON, mage.cards.r.RivenTurnbull.class)); + cards.add(new SetCardInfo("Rohgahh of Kher Keep", 255, Rarity.RARE, mage.cards.r.RohgahhOfKherKeep.class)); + cards.add(new SetCardInfo("Rubinia Soulsinger", 256, Rarity.RARE, mage.cards.r.RubiniaSoulsinger.class)); + cards.add(new SetCardInfo("Rust", 203, Rarity.COMMON, mage.cards.r.Rust.class)); + cards.add(new SetCardInfo("Sea Kings' Blessing", 75, Rarity.UNCOMMON, mage.cards.s.SeaKingsBlessing.class)); + cards.add(new SetCardInfo("Seeker", 35, Rarity.UNCOMMON, mage.cards.s.Seeker.class)); + cards.add(new SetCardInfo("Segovian Leviathan", 76, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); + cards.add(new SetCardInfo("Sentinel", 294, Rarity.RARE, mage.cards.s.Sentinel.class)); + cards.add(new SetCardInfo("Serpent Generator", 295, Rarity.RARE, mage.cards.s.SerpentGenerator.class)); + cards.add(new SetCardInfo("Shield Wall", 36, Rarity.UNCOMMON, mage.cards.s.ShieldWall.class)); + cards.add(new SetCardInfo("Shimian Night Stalker", 116, Rarity.UNCOMMON, mage.cards.s.ShimianNightStalker.class)); + cards.add(new SetCardInfo("Sir Shandlar of Eberyn", 257, Rarity.UNCOMMON, mage.cards.s.SirShandlarOfEberyn.class)); + cards.add(new SetCardInfo("Sivitri Scarzam", 258, Rarity.UNCOMMON, mage.cards.s.SivitriScarzam.class)); + cards.add(new SetCardInfo("Sol'kanar the Swamp King", 259, Rarity.RARE, mage.cards.s.SolkanarTheSwampKing.class)); + cards.add(new SetCardInfo("Spectral Cloak", 78, Rarity.UNCOMMON, mage.cards.s.SpectralCloak.class)); + cards.add(new SetCardInfo("Spinal Villain", 164, Rarity.RARE, mage.cards.s.SpinalVillain.class)); + cards.add(new SetCardInfo("Spirit Link", 37, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class)); + cards.add(new SetCardInfo("Spirit Shackle", 117, Rarity.COMMON, mage.cards.s.SpiritShackle.class)); + cards.add(new SetCardInfo("Spiritual Sanctuary", 38, Rarity.RARE, mage.cards.s.SpiritualSanctuary.class)); + cards.add(new SetCardInfo("Stangg", 260, Rarity.RARE, mage.cards.s.Stangg.class)); + cards.add(new SetCardInfo("Storm Seeker", 205, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class)); + cards.add(new SetCardInfo("Storm World", 165, Rarity.RARE, mage.cards.s.StormWorld.class)); + cards.add(new SetCardInfo("Sunastian Falconer", 261, Rarity.UNCOMMON, mage.cards.s.SunastianFalconer.class)); + cards.add(new SetCardInfo("Sword of the Ages", 296, Rarity.RARE, mage.cards.s.SwordOfTheAges.class)); + cards.add(new SetCardInfo("Sylvan Library", 207, Rarity.UNCOMMON, mage.cards.s.SylvanLibrary.class)); + cards.add(new SetCardInfo("Sylvan Paradise", 208, Rarity.UNCOMMON, mage.cards.s.SylvanParadise.class)); + cards.add(new SetCardInfo("Syphon Soul", 118, Rarity.COMMON, mage.cards.s.SyphonSoul.class)); + cards.add(new SetCardInfo("Telekinesis", 79, Rarity.RARE, mage.cards.t.Telekinesis.class)); + cards.add(new SetCardInfo("Teleport", 80, Rarity.RARE, mage.cards.t.Teleport.class)); + cards.add(new SetCardInfo("Tetsuo Umezawa", 262, Rarity.RARE, mage.cards.t.TetsuoUmezawa.class)); + cards.add(new SetCardInfo("The Abyss", 120, Rarity.RARE, mage.cards.t.TheAbyss.class)); + cards.add(new SetCardInfo("The Brute", 167, Rarity.COMMON, mage.cards.t.TheBrute.class)); + cards.add(new SetCardInfo("The Lady of the Mountain", 263, Rarity.UNCOMMON, mage.cards.t.TheLadyOfTheMountain.class)); + cards.add(new SetCardInfo("The Tabernacle at Pendrell Vale", 307, Rarity.RARE, mage.cards.t.TheTabernacleAtPendrellVale.class)); + cards.add(new SetCardInfo("The Wretched", 121, Rarity.RARE, mage.cards.t.TheWretched.class)); + cards.add(new SetCardInfo("Thunder Spirit", 39, Rarity.RARE, mage.cards.t.ThunderSpirit.class)); + cards.add(new SetCardInfo("Time Elemental", 81, Rarity.RARE, mage.cards.t.TimeElemental.class)); + cards.add(new SetCardInfo("Tobias Andrion", 264, Rarity.UNCOMMON, mage.cards.t.TobiasAndrion.class)); + cards.add(new SetCardInfo("Tor Wauki", 265, Rarity.UNCOMMON, mage.cards.t.TorWauki.class)); + cards.add(new SetCardInfo("Torsten Von Ursus", 266, Rarity.UNCOMMON, mage.cards.t.TorstenVonUrsus.class)); + cards.add(new SetCardInfo("Touch of Darkness", 122, Rarity.UNCOMMON, mage.cards.t.TouchOfDarkness.class)); + cards.add(new SetCardInfo("Transmutation", 123, Rarity.COMMON, mage.cards.t.Transmutation.class)); + cards.add(new SetCardInfo("Triassic Egg", 297, Rarity.RARE, mage.cards.t.TriassicEgg.class)); + cards.add(new SetCardInfo("Tuknir Deathlock", 267, Rarity.RARE, mage.cards.t.TuknirDeathlock.class)); + cards.add(new SetCardInfo("Tundra Wolves", 40, Rarity.COMMON, mage.cards.t.TundraWolves.class)); + cards.add(new SetCardInfo("Typhoon", 209, Rarity.RARE, mage.cards.t.Typhoon.class)); + cards.add(new SetCardInfo("Undertow", 82, Rarity.UNCOMMON, mage.cards.u.Undertow.class)); + cards.add(new SetCardInfo("Underworld Dreams", 124, Rarity.UNCOMMON, mage.cards.u.UnderworldDreams.class)); + cards.add(new SetCardInfo("Untamed Wilds", 210, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); + cards.add(new SetCardInfo("Ur-Drago", 268, Rarity.RARE, mage.cards.u.UrDrago.class)); + cards.add(new SetCardInfo("Urborg", 310, Rarity.UNCOMMON, mage.cards.u.Urborg.class)); + cards.add(new SetCardInfo("Vaevictis Asmadi", 269, Rarity.RARE, mage.cards.v.VaevictisAsmadi.class)); + cards.add(new SetCardInfo("Vampire Bats", 125, Rarity.COMMON, mage.cards.v.VampireBats.class)); + cards.add(new SetCardInfo("Visions", 41, Rarity.UNCOMMON, mage.cards.v.Visions.class)); + cards.add(new SetCardInfo("Walking Dead", 126, Rarity.COMMON, mage.cards.w.WalkingDead.class)); + cards.add(new SetCardInfo("Wall of Caltrops", 42, Rarity.COMMON, mage.cards.w.WallOfCaltrops.class)); + cards.add(new SetCardInfo("Wall of Dust", 168, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class)); + cards.add(new SetCardInfo("Wall of Earth", 169, Rarity.COMMON, mage.cards.w.WallOfEarth.class)); + cards.add(new SetCardInfo("Wall of Heat", 170, Rarity.COMMON, mage.cards.w.WallOfHeat.class)); + cards.add(new SetCardInfo("Wall of Light", 43, Rarity.UNCOMMON, mage.cards.w.WallOfLight.class)); + cards.add(new SetCardInfo("Wall of Opposition", 171, Rarity.RARE, mage.cards.w.WallOfOpposition.class)); + cards.add(new SetCardInfo("Wall of Putrid Flesh", 127, Rarity.UNCOMMON, mage.cards.w.WallOfPutridFlesh.class)); + cards.add(new SetCardInfo("Wall of Vapor", 84, Rarity.COMMON, mage.cards.w.WallOfVapor.class)); + cards.add(new SetCardInfo("Wall of Wonder", 85, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class)); + cards.add(new SetCardInfo("Whirling Dervish", 211, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class)); + cards.add(new SetCardInfo("White Mana Battery", 299, Rarity.UNCOMMON, mage.cards.w.WhiteManaBattery.class)); + cards.add(new SetCardInfo("Willow Satyr", 212, Rarity.RARE, mage.cards.w.WillowSatyr.class)); + cards.add(new SetCardInfo("Winds of Change", 172, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class)); + cards.add(new SetCardInfo("Winter Blast", 213, Rarity.RARE, mage.cards.w.WinterBlast.class)); + cards.add(new SetCardInfo("Wolverine Pack", 214, Rarity.COMMON, mage.cards.w.WolverinePack.class)); + cards.add(new SetCardInfo("Wood Elemental", 215, Rarity.RARE, mage.cards.w.WoodElemental.class)); + cards.add(new SetCardInfo("Xira Arien", 270, Rarity.RARE, mage.cards.x.XiraArien.class)); + cards.add(new SetCardInfo("Zephyr Falcon", 86, Rarity.COMMON, mage.cards.z.ZephyrFalcon.class)); + } +} From cfb51def3d9e8ca63d763b9c54c97029e9f5218e Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 13 Nov 2018 03:38:54 +0400 Subject: [PATCH 126/167] Tests: added realtime checks for life and exile (#4936) --- .../java/org/mage/test/player/TestPlayer.java | 35 +++++++++++++++++++ .../base/impl/CardTestPlayerAPIImpl.java | 10 ++++++ 2 files changed, 45 insertions(+) diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 0fa4a84a09..ae5cdf3ca3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -43,9 +43,11 @@ import mage.player.ai.ComputerPlayer; import mage.players.Library; import mage.players.ManaPool; import mage.players.Player; +import mage.players.PlayerList; import mage.players.net.UserData; import mage.target.*; import mage.target.common.*; +import org.apache.log4j.Logger; import org.junit.Assert; import org.junit.Ignore; @@ -64,6 +66,8 @@ import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*; @Ignore public class TestPlayer implements Player { + private static final Logger logger = Logger.getLogger(TestPlayer.class); + private int maxCallsWithoutAction = 100; private int foundNoAction = 0; private boolean AIPlayer; @@ -524,6 +528,13 @@ public class TestPlayer implements Player { checkProccessed = true; } + // check PT: life + if (params[0].equals(CHECK_COMMAND_LIFE) && params.length == 2) { + assertLife(action, game, computerPlayer, Integer.parseInt(params[1])); + actions.remove(action); + checkProccessed = true; + } + // check ability: card name, ability class, must have if (params[0].equals(CHECK_COMMAND_ABILITY) && params.length == 4) { assertAbility(action, game, computerPlayer, params[1], params[2], Boolean.parseBoolean(params[3])); @@ -538,6 +549,13 @@ public class TestPlayer implements Player { checkProccessed = true; } + // check exile count: card name, count + if (params[0].equals(CHECK_COMMAND_EXILE_COUNT) && params.length == 3) { + assertExileCount(action, game, computerPlayer, params[1], Integer.parseInt(params[2])); + actions.remove(action); + checkProccessed = true; + } + // check hand count: count if (params[0].equals(CHECK_COMMAND_HAND_COUNT) && params.length == 2) { assertHandCount(action, game, computerPlayer, Integer.parseInt(params[1])); @@ -610,6 +628,11 @@ public class TestPlayer implements Player { Toughness, perm.getToughness().getValue()); } + private void assertLife(PlayerAction action, Game game, Player player, int Life) { + Assert.assertEquals(action.getActionName() + " - " + player.getName() + " have wrong life: " + player.getLife() + " <> " + Life, + Life, player.getLife()); + } + private void assertAbility(PlayerAction action, Game game, Player player, String permanentName, String abilityClass, boolean mustHave) { Permanent perm = findPermanentWithAssert(action, game, player, permanentName); @@ -639,6 +662,17 @@ public class TestPlayer implements Player { Assert.assertEquals(action.getActionName() + " - permanent " + permanentName + " must exists in " + count + " instances", count, foundedCount); } + private void assertExileCount(PlayerAction action, Game game, Player player, String permanentName, int count) { + int foundedCount = 0; + for (Card card : game.getExile().getAllCards(game)) { + if (card.getName().equals(permanentName) && card.isOwnedBy(player.getId())) { + foundedCount++; + } + } + + Assert.assertEquals(action.getActionName() + " - card " + permanentName + " must exists in exile zone with " + count + " instances", count, foundedCount); + } + private void assertHandCount(PlayerAction action, Game game, Player player, int count) { Assert.assertEquals(action.getActionName() + " - hand must contain " + count, count, player.getHand().size()); } @@ -1092,6 +1126,7 @@ public class TestPlayer implements Player { } } } + return computerPlayer.choose(outcome, target, sourceId, game, options); } diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index bf2a95d870..c986d0df0f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -49,8 +49,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement public static final String NO_TARGET = "NO_TARGET"; public static final String CHECK_COMMAND_PT = "PT"; + public static final String CHECK_COMMAND_LIFE = "LIFE"; public static final String CHECK_COMMAND_ABILITY = "ABILITY"; public static final String CHECK_COMMAND_PERMANENT_COUNT = "PERMANENT_COUNT"; + public static final String CHECK_COMMAND_EXILE_COUNT = "EXILE_COUNT"; public static final String CHECK_COMMAND_HAND_COUNT = "HAND_COUNT"; public static final String CHECK_COMMAND_COLOR = "COLOR"; public static final String CHECK_COMMAND_SUBTYPE = "SUBTYPE"; @@ -240,6 +242,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement check(checkName, turnNum, step, player, CHECK_COMMAND_PT, permanentName, power.toString(), toughness.toString()); } + public void checkLife(String checkName, int turnNum, PhaseStep step, TestPlayer player, Integer life) { + check(checkName, turnNum, step, player, CHECK_COMMAND_LIFE, life.toString()); + } + public void checkAbility(String checkName, int turnNum, PhaseStep step, TestPlayer player, String permanentName, Class abilityClass, Boolean mustHave) { check(checkName, turnNum, step, player, CHECK_COMMAND_ABILITY, permanentName, abilityClass.getName(), mustHave.toString()); } @@ -248,6 +254,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement check(checkName, turnNum, step, player, CHECK_COMMAND_PERMANENT_COUNT, permanentName, count.toString()); } + public void checkExileCount(String checkName, int turnNum, PhaseStep step, TestPlayer player, String permanentName, Integer count) { + check(checkName, turnNum, step, player, CHECK_COMMAND_EXILE_COUNT, permanentName, count.toString()); + } + public void checkHandCount(String checkName, int turnNum, PhaseStep step, TestPlayer player, Integer count) { check(checkName, turnNum, step, player, CHECK_COMMAND_HAND_COUNT, count.toString()); } From 69e795e75e0961e920b831e0798c447bce6d9201 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 12 Nov 2018 17:55:45 -0600 Subject: [PATCH 127/167] - Added Power Taint --- Mage.Sets/src/mage/cards/p/PowerTaint.java | 61 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 1 + 2 files changed, 62 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PowerTaint.java diff --git a/Mage.Sets/src/mage/cards/p/PowerTaint.java b/Mage.Sets/src/mage/cards/p/PowerTaint.java new file mode 100644 index 0000000000..c985eabd11 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PowerTaint.java @@ -0,0 +1,61 @@ +package mage.cards.p; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetEnchantmentPermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author jeffwadsworth + */ +public final class PowerTaint extends CardImpl { + + public PowerTaint(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant enchantment + TargetPermanent auraTarget = new TargetEnchantmentPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of the upkeep of enchanted enchantment's controller, that player loses 2 life unless he or she pays {2}. + Effect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new LoseLifeTargetEffect(2), + new ManaCostsImpl("{2}"), "that player loses 2 life unless he or she pays {2}"); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, + TargetController.CONTROLLER_ATTACHED_TO, false, true, + "At the beginning of the upkeep of enchanted enchantment's controller, ")); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public PowerTaint(final PowerTaint card) { + super(card); + } + + @Override + public PowerTaint copy() { + return new PowerTaint(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 45b950c405..6d65f27d39 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -237,6 +237,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Polluted Mire", 323, Rarity.COMMON, mage.cards.p.PollutedMire.class)); cards.add(new SetCardInfo("Pouncing Jaguar", 269, Rarity.COMMON, mage.cards.p.PouncingJaguar.class)); cards.add(new SetCardInfo("Power Sink", 89, Rarity.COMMON, mage.cards.p.PowerSink.class)); + cards.add(new SetCardInfo("Power Taint", 90, Rarity.COMMON, mage.cards.p.PowerTaint.class)); cards.add(new SetCardInfo("Presence of the Master", 32, Rarity.UNCOMMON, mage.cards.p.PresenceOfTheMaster.class)); cards.add(new SetCardInfo("Priest of Gix", 150, Rarity.UNCOMMON, mage.cards.p.PriestOfGix.class)); cards.add(new SetCardInfo("Priest of Titania", 270, Rarity.COMMON, mage.cards.p.PriestOfTitania.class)); From 8d4f44bee6ef98a67e70d8a6bb051a12f007f1e6 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 13 Nov 2018 11:27:44 -0600 Subject: [PATCH 128/167] - Added Veil of Birds and Veiled Apparition. --- Mage.Sets/src/mage/cards/v/VeilOfBirds.java | 66 +++++++++++++++++ .../src/mage/cards/v/VeiledApparition.java | 74 +++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 2 + 3 files changed, 142 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VeilOfBirds.java create mode 100644 Mage.Sets/src/mage/cards/v/VeiledApparition.java diff --git a/Mage.Sets/src/mage/cards/v/VeilOfBirds.java b/Mage.Sets/src/mage/cards/v/VeilOfBirds.java new file mode 100644 index 0000000000..53e476fca4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeilOfBirds.java @@ -0,0 +1,66 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class VeilOfBirds extends CardImpl { + + private static final FilterSpell filter = new FilterSpell(); + + public VeilOfBirds(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + + // When an opponent casts a spell, if Veil of Birds is an enchantment, Veil of Birds becomes a 1/1 Bird creature with flying. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new VeilOfBirdsToken(), "", Duration.WhileOnBattlefield, true, false), + filter, false); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "Whenever an opponent casts a spell, if Veil of Birds is an enchantment, Veil of Birds becomes a 1/1 Bird creature with flying.")); + } + + public VeilOfBirds(final VeilOfBirds card) { + super(card); + } + + @Override + public VeilOfBirds copy() { + return new VeilOfBirds(this); + } +} + +class VeilOfBirdsToken extends TokenImpl { + + public VeilOfBirdsToken() { + super("Bird", "1/1 creature with flying"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.BIRD); + power = new MageInt(1); + toughness = new MageInt(1); + this.addAbility(FlyingAbility.getInstance()); + } + + public VeilOfBirdsToken(final VeilOfBirdsToken token) { + super(token); + } + + public VeilOfBirdsToken copy() { + return new VeilOfBirdsToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VeiledApparition.java b/Mage.Sets/src/mage/cards/v/VeiledApparition.java new file mode 100644 index 0000000000..2bf24f1339 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeiledApparition.java @@ -0,0 +1,74 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.DoUnlessControllerPaysEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +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.FilterSpell; +import mage.filter.StaticFilters; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class VeiledApparition extends CardImpl { + + private static final FilterSpell filter = new FilterSpell(); + + public VeiledApparition(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + + + // When an opponent casts a spell, if Veiled Apparition is an enchantment, Veiled Apparition becomes a 3/3 Illusion creature with flying and "At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}." + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new VeilApparitionToken(), "", Duration.WhileOnBattlefield, true, false), + filter, false); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "Whenever an opponent casts a spell, if Veiled Apparition is an enchantment, Veiled Apparition becomes a 3/3 Illusion creature with flying and \"At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}.")); + + } + + public VeiledApparition(final VeiledApparition card) { + super(card); + } + + @Override + public VeiledApparition copy() { + return new VeiledApparition(this); + } +} + +class VeilApparitionToken extends TokenImpl { + + public VeilApparitionToken() { + super("Illusion", "3/3 Illusion creature with flying and \"At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}."); + cardType.add(CardType.CREATURE); + subtype.add(SubType.ILLUSION); + power = new MageInt(3); + toughness = new MageInt(3); + Ability ability = new BeginningOfUpkeepTriggeredAbility(new DoUnlessControllerPaysEffect(new SacrificeSourceEffect(), new ManaCostsImpl("{1}{U}")), TargetController.YOU, false); + this.addAbility(ability); + } + + public VeilApparitionToken(final VeilApparitionToken token) { + super(token); + } + + public VeilApparitionToken copy() { + return new VeilApparitionToken(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 6d65f27d39..5d3633fe30 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -335,6 +335,8 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Urza's Armor", 313, Rarity.UNCOMMON, mage.cards.u.UrzasArmor.class)); cards.add(new SetCardInfo("Vampiric Embrace", 164, Rarity.UNCOMMON, mage.cards.v.VampiricEmbrace.class)); cards.add(new SetCardInfo("Vebulid", 165, Rarity.RARE, mage.cards.v.Vebulid.class)); + cards.add(new SetCardInfo("Veil of Birds", 106, Rarity.COMMON, mage.cards.v.VeilOfBirds.class)); + cards.add(new SetCardInfo("Veiled Apparition", 107, Rarity.UNCOMMON, mage.cards.v.VeiledApparition.class)); cards.add(new SetCardInfo("Venomous Fangs", 280, Rarity.COMMON, mage.cards.v.VenomousFangs.class)); cards.add(new SetCardInfo("Vernal Bloom", 281, Rarity.RARE, mage.cards.v.VernalBloom.class)); cards.add(new SetCardInfo("Viashino Outrider", 223, Rarity.COMMON, mage.cards.v.ViashinoOutrider.class)); From 44ed8cebb7364e13b10fdcb062622936657e8a03 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 14 Nov 2018 02:10:40 +0400 Subject: [PATCH 129/167] * Pemmin's Aura - Fixed exception error after enchanted creature was dies; --- Mage.Sets/src/mage/cards/p/PemminsAura.java | 46 +++++++++++---------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PemminsAura.java b/Mage.Sets/src/mage/cards/p/PemminsAura.java index 89139bc99d..4cd260a1ac 100644 --- a/Mage.Sets/src/mage/cards/p/PemminsAura.java +++ b/Mage.Sets/src/mage/cards/p/PemminsAura.java @@ -1,7 +1,6 @@ package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -17,20 +16,16 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.choices.Choice; import mage.choices.ChoiceImpl; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author fireshoes */ public final class PemminsAura extends CardImpl { @@ -94,21 +89,28 @@ class PemminsAuraBoostEnchantedEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Permanent enchantment = game.getPermanent(source.getSourceId()); - Permanent creature = game.getPermanent(enchantment.getAttachedTo()); - if (controller != null && creature != null) { - Choice choice = new ChoiceImpl(true); - choice.setMessage("Select how to boost"); - choice.getChoices().add(CHOICE_1); - choice.getChoices().add(CHOICE_2); - if (controller.choose(outcome, choice, game)) { - if (choice.getChoice().equals(CHOICE_1)) { - game.addEffect(new BoostEnchantedEffect(+1, -1, Duration.EndOfTurn), source); - } else { - game.addEffect(new BoostEnchantedEffect(-1, +1, Duration.EndOfTurn), source); - } - return true; - } + if (controller == null || enchantment == null) { + return false; } + + Permanent creature = game.getPermanent(enchantment.getAttachedTo()); + if (creature == null) { + return false; + } + + Choice choice = new ChoiceImpl(true); + choice.setMessage("Select how to boost"); + choice.getChoices().add(CHOICE_1); + choice.getChoices().add(CHOICE_2); + if (controller.choose(outcome, choice, game)) { + if (choice.getChoice().equals(CHOICE_1)) { + game.addEffect(new BoostEnchantedEffect(+1, -1, Duration.EndOfTurn), source); + } else { + game.addEffect(new BoostEnchantedEffect(-1, +1, Duration.EndOfTurn), source); + } + return true; + } + return false; } } From 51dce7a4477b1429679585d222d10bb1d785070f Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 14 Nov 2018 02:14:29 +0400 Subject: [PATCH 130/167] Karametra, God of Harvests - Fixed typo in card text --- Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java b/Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java index 2325c45a86..6ccd4c9f3b 100644 --- a/Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java +++ b/Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java @@ -25,7 +25,7 @@ import mage.target.common.TargetCardInLibrary; */ public final class KarametraGodOfHarvests extends CardImpl { - private static final FilterCard filter = new FilterCard("a Forest or Plains card"); + private static final FilterCard filter = new FilterCard("Forest or Plains card"); static { filter.add(Predicates.or( From d3bfeccb0133ac8ee8d626a79a57c9cafb3f4257 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 13 Nov 2018 18:29:12 -0600 Subject: [PATCH 131/167] - Added Veiled Sentry, Hidden Predators, Veiled Crocodile, Veiled Serpent. --- .../src/mage/cards/h/HiddenPredators.java | 131 ++++++++++++++++++ .../src/mage/cards/v/VeiledCrocodile.java | 127 +++++++++++++++++ Mage.Sets/src/mage/cards/v/VeiledSentry.java | 114 +++++++++++++++ Mage.Sets/src/mage/cards/v/VeiledSerpent.java | 75 ++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 4 + 5 files changed, 451 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HiddenPredators.java create mode 100644 Mage.Sets/src/mage/cards/v/VeiledCrocodile.java create mode 100644 Mage.Sets/src/mage/cards/v/VeiledSentry.java create mode 100644 Mage.Sets/src/mage/cards/v/VeiledSerpent.java diff --git a/Mage.Sets/src/mage/cards/h/HiddenPredators.java b/Mage.Sets/src/mage/cards/h/HiddenPredators.java new file mode 100644 index 0000000000..f5ff50d09b --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HiddenPredators.java @@ -0,0 +1,131 @@ +package mage.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class HiddenPredators extends CardImpl { + + public HiddenPredators(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); + + // When an opponent controls a creature with power 4 or greater, if Hidden Predators is an enchantment, Hidden Predators becomes a 4/4 Beast creature. + this.addAbility(new HiddenPredatorsStateTriggeredAbility()); + } + + public HiddenPredators(final HiddenPredators card) { + super(card); + } + + @Override + public HiddenPredators copy() { + return new HiddenPredators(this); + } +} + +class HiddenPredatorsStateTriggeredAbility extends StateTriggeredAbility { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3)); + } + + public HiddenPredatorsStateTriggeredAbility() { + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new HiddenPredatorsToken(), "", Duration.Custom, true, false)); + } + + public HiddenPredatorsStateTriggeredAbility(final HiddenPredatorsStateTriggeredAbility ability) { + super(ability); + } + + @Override + public HiddenPredatorsStateTriggeredAbility copy() { + return new HiddenPredatorsStateTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return !game.getBattlefield().getAllActivePermanents(filter, game).isEmpty(); + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + } + + @Override + public boolean canTrigger(Game game) { + //20100716 - 603.8 + Boolean triggered = (Boolean) game.getState().getValue(getSourceId().toString() + "triggered"); + if (triggered == null) { + triggered = Boolean.FALSE; + } + return !triggered; + } + + @Override + public void trigger(Game game, UUID controllerId) { + //20100716 - 603.8 + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE); + super.trigger(game, controllerId); + } + + @Override + public boolean resolve(Game game) { + //20100716 - 603.8 + boolean result = super.resolve(game); + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + return result; + } + + @Override + public void counter(Game game) { + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + } + + @Override + public String getRule() { + return new StringBuilder("When an opponent controls a creature with 4 or greater power, if {this} is an enchantment, ").append(super.getRule()).toString(); + } + +} + +class HiddenPredatorsToken extends TokenImpl { + + public HiddenPredatorsToken() { + super("Beast", "4/4 Beast creature"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.BEAST); + power = new MageInt(4); + toughness = new MageInt(4); + } + + public HiddenPredatorsToken(final HiddenPredatorsToken token) { + super(token); + } + + public HiddenPredatorsToken copy() { + return new HiddenPredatorsToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java new file mode 100644 index 0000000000..c3790e5c73 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java @@ -0,0 +1,127 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +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.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.TokenImpl; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public final class VeiledCrocodile extends CardImpl { + + public VeiledCrocodile(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + // When a player has no cards in hand, if Veiled Crocodile is an enchantment, Veiled Crocodile becomes a 4/4 Crocodile creature. + this.addAbility(new VeiledCrocodileStateTriggeredAbility()); + } + + public VeiledCrocodile(final VeiledCrocodile card) { + super(card); + } + + @Override + public VeiledCrocodile copy() { + return new VeiledCrocodile(this); + } +} + +class VeiledCrocodileStateTriggeredAbility extends StateTriggeredAbility { + + public VeiledCrocodileStateTriggeredAbility() { + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new VeilCrocodileToken(), "", Duration.Custom, true, false)); + } + + public VeiledCrocodileStateTriggeredAbility(final VeiledCrocodileStateTriggeredAbility ability) { + super(ability); + } + + @Override + public VeiledCrocodileStateTriggeredAbility copy() { + return new VeiledCrocodileStateTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + for (UUID playerId : game.getState().getPlayersInRange(controllerId, game)) { + Player player = game.getPlayer(playerId); + if (player != null + && player.getHand().isEmpty()) { + return true; + } + } + return false; + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + } + + @Override + public boolean canTrigger(Game game) { + //20100716 - 603.8 + Boolean triggered = (Boolean) game.getState().getValue(getSourceId().toString() + "triggered"); + if (triggered == null) { + triggered = Boolean.FALSE; + } + return !triggered; + } + + @Override + public void trigger(Game game, UUID controllerId) { + //20100716 - 603.8 + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE); + super.trigger(game, controllerId); + } + + @Override + public boolean resolve(Game game) { + //20100716 - 603.8 + boolean result = super.resolve(game); + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + return result; + } + + @Override + public void counter(Game game) { + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + } + + @Override + public String getRule() { + return new StringBuilder("When a player has no cards in hand, if {this} is an enchantment, ").append(super.getRule()).toString(); + } + +} + +class VeilCrocodileToken extends TokenImpl { + + public VeilCrocodileToken() { + super("Crocodile", "4/4 Crocodile creature"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.CROCODILE); + power = new MageInt(4); + toughness = new MageInt(4); + } + + public VeilCrocodileToken(final VeilCrocodileToken token) { + super(token); + } + + public VeilCrocodileToken copy() { + return new VeilCrocodileToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VeiledSentry.java b/Mage.Sets/src/mage/cards/v/VeiledSentry.java new file mode 100644 index 0000000000..8c79053975 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeiledSentry.java @@ -0,0 +1,114 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import static mage.constants.Layer.PTChangingEffects_7; +import static mage.constants.Layer.TypeChangingEffects_4; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.constants.SubLayer; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; + +/** + * + * @author jeffwadsworth + */ +public final class VeiledSentry extends CardImpl { + + public VeiledSentry(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + + // When an opponent casts a spell, if Veiled Sentry is an enchantment, Veiled Sentry becomes an Illusion creature with power and toughness each equal to that spell's converted mana cost. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, new VeiledSentryEffect(), new FilterSpell(), false, SetTargetPointer.SPELL); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "Whenever an opponent casts a spell, if Veiled Sentry is an enchantment, Veil Sentry becomes an Illusion creature with power and toughness equal to that spell's converted mana cost.")); + + } + + public VeiledSentry(final VeiledSentry card) { + super(card); + } + + @Override + public VeiledSentry copy() { + return new VeiledSentry(this); + } +} + +class VeiledSentryEffect extends ContinuousEffectImpl { + + public VeiledSentryEffect() { + super(Duration.Custom, Outcome.BecomeCreature); + staticText = "{this} becomes an Illusion creature with power and toughness equal to that spell's converted mana cost"; + } + + public VeiledSentryEffect(final VeiledSentryEffect effect) { + super(effect); + } + + @Override + public VeiledSentryEffect copy() { + return new VeiledSentryEffect(this); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + Permanent veiledSentry = game.getPermanent(source.getSourceId()); + Spell spellCast = game.getSpell(targetPointer.getFirst(game, source)); + if (spellCast != null) { + game.getState().setValue(source + "cmcSpell", spellCast.getConvertedManaCost()); + } + if (veiledSentry == null) { + return false; + } + switch (layer) { + case TypeChangingEffects_4: + if (sublayer == SubLayer.NA) { + if (!veiledSentry.isCreature()) { + veiledSentry.addCardType(CardType.CREATURE); + } + if (!veiledSentry.getSubtype(game).contains(SubType.ILLUSION)) { + veiledSentry.getSubtype(game).add(SubType.ILLUSION); + } + } + break; + + case PTChangingEffects_7: + if (game.getState().getValue(source + "cmcSpell") != null) { + int cmc = (int) game.getState().getValue(source + "cmcSpell"); + if (sublayer == SubLayer.SetPT_7b) { + veiledSentry.addPower(cmc); + veiledSentry.addToughness(cmc); + } + } + } + return true; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.PTChangingEffects_7 + || layer == Layer.TypeChangingEffects_4; + } +} diff --git a/Mage.Sets/src/mage/cards/v/VeiledSerpent.java b/Mage.Sets/src/mage/cards/v/VeiledSerpent.java new file mode 100644 index 0000000000..216133ebfd --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VeiledSerpent.java @@ -0,0 +1,75 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.combat.CantAttackUnlessDefenderControllsPermanent; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class VeiledSerpent extends CardImpl { + + public VeiledSerpent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + // When an opponent casts a spell, if Veiled Serpent is an enchantment, Veiled Serpent becomes a 4/4 Serpent creature that can't attack unless defending player controls an Island. + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new VeiledSerpentToken(), "", Duration.WhileOnBattlefield, true, false), + new FilterSpell(), false); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "Whenever an opponent casts a spell, if Veiled Serpent is an enchantment, Veiled Serpent becomes a 4/4 Serpent creature that can't attack unless defending player controls an Island.")); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public VeiledSerpent(final VeiledSerpent card) { + super(card); + } + + @Override + public VeiledSerpent copy() { + return new VeiledSerpent(this); + } +} + +class VeiledSerpentToken extends TokenImpl { + + public VeiledSerpentToken() { + super("Serpent", "4/4 Serpent creature"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.SERPENT); + power = new MageInt(4); + toughness = new MageInt(4); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new CantAttackUnlessDefenderControllsPermanent( + new FilterLandPermanent(SubType.ISLAND, "an Island")))); + } + + public VeiledSerpentToken(final VeiledSerpentToken token) { + super(token); + } + + public VeiledSerpentToken copy() { + return new VeiledSerpentToken(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 5d3633fe30..64db33f2e2 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -164,6 +164,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Hidden Ancients", 260, Rarity.UNCOMMON, mage.cards.h.HiddenAncients.class)); cards.add(new SetCardInfo("Hidden Guerrillas", 261, Rarity.UNCOMMON, mage.cards.h.HiddenGuerrillas.class)); cards.add(new SetCardInfo("Hidden Herd", 262, Rarity.RARE, mage.cards.h.HiddenHerd.class)); + cards.add(new SetCardInfo("Hidden Predators", 263, Rarity.RARE, mage.cards.h.HiddenPredators.class)); cards.add(new SetCardInfo("Hidden Spider", 264, Rarity.COMMON, mage.cards.h.HiddenSpider.class)); cards.add(new SetCardInfo("Hidden Stag", 265, Rarity.RARE, mage.cards.h.HiddenStag.class)); cards.add(new SetCardInfo("Hollow Dogs", 137, Rarity.COMMON, mage.cards.h.HollowDogs.class)); @@ -337,6 +338,9 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Vebulid", 165, Rarity.RARE, mage.cards.v.Vebulid.class)); cards.add(new SetCardInfo("Veil of Birds", 106, Rarity.COMMON, mage.cards.v.VeilOfBirds.class)); cards.add(new SetCardInfo("Veiled Apparition", 107, Rarity.UNCOMMON, mage.cards.v.VeiledApparition.class)); + cards.add(new SetCardInfo("Veiled Crocodile", 108, Rarity.RARE, mage.cards.v.VeiledCrocodile.class)); + cards.add(new SetCardInfo("Veiled Sentry", 109, Rarity.UNCOMMON, mage.cards.v.VeiledSentry.class)); + cards.add(new SetCardInfo("Veiled Serpent", 110, Rarity.COMMON, mage.cards.v.VeiledSerpent.class)); cards.add(new SetCardInfo("Venomous Fangs", 280, Rarity.COMMON, mage.cards.v.VenomousFangs.class)); cards.add(new SetCardInfo("Vernal Bloom", 281, Rarity.RARE, mage.cards.v.VernalBloom.class)); cards.add(new SetCardInfo("Viashino Outrider", 223, Rarity.COMMON, mage.cards.v.ViashinoOutrider.class)); From 9d8d623341aa5edb044eb29fc5a831ae1977a38e Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 13 Nov 2018 18:36:03 -0600 Subject: [PATCH 132/167] - Text fixes for Opal Acrolith. --- Mage.Sets/src/mage/cards/o/OpalAcrolith.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java index 5e8e17fbda..235bf3a362 100644 --- a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java +++ b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java @@ -37,7 +37,7 @@ public final class OpalAcrolith extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // Whenever an opponent casts a creature spell, if Opal Acrolith is an enchantment, Opal Acrolith becomes a 2/4 Soldier creature. - TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalAcrolithSoldier(), "", Duration.WhileOnBattlefield, true, false), + TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalAcrolithToken(), "", Duration.WhileOnBattlefield, true, false), filter, false); this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), "Whenever an opponent casts a creature spell, if Opal Acrolith is an enchantment, Opal Acrolith becomes a 2/4 Soldier creature.")); @@ -57,21 +57,21 @@ public final class OpalAcrolith extends CardImpl { } } -class OpalAcrolithSoldier extends TokenImpl { +class OpalAcrolithToken extends TokenImpl { - public OpalAcrolithSoldier() { - super("Soldier", "2/4 Ape creature"); + public OpalAcrolithToken() { + super("Soldier", "2/4 Soldier creature"); cardType.add(CardType.CREATURE); subtype.add(SubType.SOLDIER); power = new MageInt(2); toughness = new MageInt(4); } - public OpalAcrolithSoldier(final OpalAcrolithSoldier token) { + public OpalAcrolithToken(final OpalAcrolithToken token) { super(token); } - public OpalAcrolithSoldier copy() { - return new OpalAcrolithSoldier(this); + public OpalAcrolithToken copy() { + return new OpalAcrolithToken(this); } } From e389b95738c74ee95d567cbdd75b1324b844d0f8 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 14 Nov 2018 05:02:29 +0400 Subject: [PATCH 133/167] * Fixed exception error on copy of copy of aura effects for some cards (Estrid's masks, Animate Dead, etc); * Fixed wrong copy effects on rollbacks or errors; --- .../effects/common/CopyPermanentEffect.java | 87 +++++++++++++------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopyPermanentEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopyPermanentEffect.java index d74258916f..c8aeb347db 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopyPermanentEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopyPermanentEffect.java @@ -1,12 +1,12 @@ package mage.abilities.effects.common; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.EnchantAbility; import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.FilterPermanent; @@ -20,8 +20,9 @@ import mage.target.TargetPermanent; import mage.util.functions.ApplyToPermanent; import mage.util.functions.EmptyApplyToPermanent; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public class CopyPermanentEffect extends OneShotEffect { @@ -59,7 +60,9 @@ public class CopyPermanentEffect extends OneShotEffect { super(effect); this.filter = effect.filter.copy(); this.applier = effect.applier; - this.bluePrintPermanent = effect.bluePrintPermanent; + if (effect.bluePrintPermanent != null) { + this.bluePrintPermanent = effect.bluePrintPermanent.copy(); + } this.useTargetOfAbility = effect.useTargetOfAbility; } @@ -84,42 +87,70 @@ public class CopyPermanentEffect extends OneShotEffect { } if (copyFromPermanent != null) { bluePrintPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, applier); - - //if object is a copy of an aura, it needs to attach - if (bluePrintPermanent.hasSubtype(SubType.AURA, game)){ + if (bluePrintPermanent == null) { + return false; + } + + // if object is a copy of an aura, it needs to attach again for new target + if (bluePrintPermanent.hasSubtype(SubType.AURA, game)) { //copied from mage.cards.c.CopyEnchantment.java - Target target = bluePrintPermanent.getSpellAbility().getTargets().get(0); + + // permanent can be attached (Estrid's Mask) or enchant (Utopia Sprawl) + // TODO: fix Animate Dead -- it's can't be copied (can't retarget) Outcome auraOutcome = Outcome.BoostCreature; + Target auraTarget = null; + + // attach - search effect in spell ability (example: cast Utopia Sprawl, cast Estrid's Invocation on it) for (Ability ability : bluePrintPermanent.getAbilities()) { if (ability instanceof SpellAbility) { for (Effect effect : ability.getEffects()) { if (effect instanceof AttachEffect) { - auraOutcome = effect.getOutcome(); + if (bluePrintPermanent.getSpellAbility().getTargets().size() > 0) { + auraTarget = bluePrintPermanent.getSpellAbility().getTargets().get(0); + auraOutcome = effect.getOutcome(); + } } } } } - - /*if this is a copy of a copy, the copy's target has been - *copied and needs to be cleared - */ - { - UUID targetId = target.getFirstTarget(); - if(targetId != null) - target.remove(targetId); + + // enchant - search in all abilities (example: cast Estrid's Invocation on enchanted creature by Estrid, the Masked second ability, cast Estrid's Invocation on it) + if (auraTarget == null) { + for (Ability ability : bluePrintPermanent.getAbilities()) { + if (ability instanceof EnchantAbility) { + if (ability.getTargets().size() > 0) { // Animate Dead don't have targets + auraTarget = ability.getTargets().get(0); + for (Effect effect : ability.getEffects()) { + // first outcome + auraOutcome = effect.getOutcome(); + } + } + } + } } - - target.setNotTarget(true); - if (controller.choose(auraOutcome, target, source.getSourceId(), game)) { - UUID targetId = target.getFirstTarget(); - Permanent targetPermanent = game.getPermanent(targetId); - Player targetPlayer = game.getPlayer(targetId); - if (targetPermanent != null) { - targetPermanent.addAttachment(sourcePermanent.getId(), game); - } else if (targetPlayer != null) { - targetPlayer.addAttachment(sourcePermanent.getId(), game); - } else { - return false; + + /* if this is a copy of a copy, the copy's target has been + * copied and needs to be cleared + */ + if (auraTarget != null) { + // clear selected target + if (auraTarget.getFirstTarget() != null) { + auraTarget.remove(auraTarget.getFirstTarget()); + } + + // select new target + auraTarget.setNotTarget(true); + if (controller.choose(auraOutcome, auraTarget, source.getSourceId(), game)) { + UUID targetId = auraTarget.getFirstTarget(); + Permanent targetPermanent = game.getPermanent(targetId); + Player targetPlayer = game.getPlayer(targetId); + if (targetPermanent != null) { + targetPermanent.addAttachment(sourcePermanent.getId(), game); + } else if (targetPlayer != null) { + targetPlayer.addAttachment(sourcePermanent.getId(), game); + } else { + return false; + } } } } From 27b2fed8ce0178102ce81fbdff6a84f537420da4 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 14 Nov 2018 17:18:17 -0600 Subject: [PATCH 134/167] - Added Outmaneuver and Antagonism. --- Mage.Sets/src/mage/cards/a/Antagonism.java | 64 ++++++++++++++ Mage.Sets/src/mage/cards/o/Outmaneuver.java | 96 +++++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 2 + 3 files changed, 162 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/Antagonism.java create mode 100644 Mage.Sets/src/mage/cards/o/Outmaneuver.java diff --git a/Mage.Sets/src/mage/cards/a/Antagonism.java b/Mage.Sets/src/mage/cards/a/Antagonism.java new file mode 100644 index 0000000000..2bde3ac7b2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/Antagonism.java @@ -0,0 +1,64 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.game.Game; +import mage.watchers.common.BloodthirstWatcher; + +/** + * + * @author jeffwadsworth + */ +public final class Antagonism extends CardImpl { + + private static final String rule = "{this} deals 2 damage to that player unless one of his or her opponents was dealt damage this turn"; + + public Antagonism(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); + + // At the beginning of each player's end step, Antagonism deals 2 damage to that player unless one of his or her opponents was dealt damage this turn. + this.addAbility(new BeginningOfEndStepTriggeredAbility(new ConditionalOneShotEffect(new DamageTargetEffect(2), + new OpponentWasNotDealtDamageCondition(), rule), TargetController.ANY, false)); + + } + + public Antagonism(final Antagonism card) { + super(card); + } + + @Override + public Antagonism copy() { + return new Antagonism(this); + } +} + +class OpponentWasNotDealtDamageCondition implements Condition { + + public OpponentWasNotDealtDamageCondition() { + } + + @Override + public boolean apply(Game game, Ability source) { + UUID activePlayer = game.getState().getActivePlayerId(); + if (activePlayer != null) { + BloodthirstWatcher watcher = (BloodthirstWatcher) game.getState().getWatchers().get(BloodthirstWatcher.class.getSimpleName(), activePlayer); + if (watcher != null) { + return !watcher.conditionMet(); + } + } + return false; + } + + @Override + public String toString() { + return "if an opponent was dealt damage this turn"; + } +} diff --git a/Mage.Sets/src/mage/cards/o/Outmaneuver.java b/Mage.Sets/src/mage/cards/o/Outmaneuver.java new file mode 100644 index 0000000000..3a604f9778 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/Outmaneuver.java @@ -0,0 +1,96 @@ +package mage.cards.o; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.BlockedPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public final class Outmaneuver extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new BlockedPredicate()); + } + + public Outmaneuver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}"); + + // X target blocked creatures assign their combat damage this turn as though they weren't blocked. + this.getSpellAbility().addEffect(new OutmaneuverEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + + } + + public Outmaneuver(final Outmaneuver card) { + super(card); + } + + @Override + public Outmaneuver copy() { + return new Outmaneuver(this); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability instanceof SpellAbility) { + ability.getTargets().clear(); + int numberOfTargets = ability.getManaCostsToPay().getX(); + numberOfTargets = Math.min(game.getBattlefield().getAllActivePermanents(filter, + ability.getControllerId(), game).size(), numberOfTargets); + ability.addTarget(new TargetCreaturePermanent(numberOfTargets, + numberOfTargets, filter, false)); + } + } +} + +class OutmaneuverEffect extends AsThoughEffectImpl { + + public OutmaneuverEffect() { + super(AsThoughEffectType.DAMAGE_NOT_BLOCKED, Duration.EndOfTurn, Outcome.Damage); + this.staticText = "X target blocked creatures assign their combat damage this turn as though they weren't blocked."; + } + + public OutmaneuverEffect(OutmaneuverEffect effect) { + super(effect); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + Permanent blockedCreature = game.getPermanent(sourceId); + if (blockedCreature != null) { + Player controller = game.getPlayer(blockedCreature.getControllerId()); + if (controller != null) { + return controller.chooseUse(Outcome.Damage, "Do you wish to assign combat damage for " + + blockedCreature.getLogName() + " as though it weren't blocked?", source, game); + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public OutmaneuverEffect copy() { + return new OutmaneuverEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 64db33f2e2..e9122c12f5 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -37,6 +37,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Angelic Chorus", 3, Rarity.RARE, mage.cards.a.AngelicChorus.class)); cards.add(new SetCardInfo("Angelic Page", 4, Rarity.COMMON, mage.cards.a.AngelicPage.class)); cards.add(new SetCardInfo("Annul", 59, Rarity.COMMON, mage.cards.a.Annul.class)); + cards.add(new SetCardInfo("Antagonism", 173, Rarity.RARE, mage.cards.a.Antagonism.class)); cards.add(new SetCardInfo("Arcane Laboratory", 60, Rarity.UNCOMMON, mage.cards.a.ArcaneLaboratory.class)); cards.add(new SetCardInfo("Arc Lightning", 174, Rarity.COMMON, mage.cards.a.ArcLightning.class)); cards.add(new SetCardInfo("Argothian Elder", 233, Rarity.UNCOMMON, mage.cards.a.ArgothianElder.class)); @@ -214,6 +215,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Opal Titan", 26, Rarity.RARE, mage.cards.o.OpalTitan.class)); cards.add(new SetCardInfo("Oppression", 143, Rarity.RARE, mage.cards.o.Oppression.class)); cards.add(new SetCardInfo("Order of Yawgmoth", 144, Rarity.UNCOMMON, mage.cards.o.OrderOfYawgmoth.class)); + cards.add(new SetCardInfo("Outmaneuver", 205, Rarity.UNCOMMON, mage.cards.o.Outmaneuver.class)); cards.add(new SetCardInfo("Pacifism", 27, Rarity.COMMON, mage.cards.p.Pacifism.class)); cards.add(new SetCardInfo("Parasitic Bond", 145, Rarity.UNCOMMON, mage.cards.p.ParasiticBond.class)); cards.add(new SetCardInfo("Pariah", 28, Rarity.RARE, mage.cards.p.Pariah.class)); From f4f24502f442ee142270e8084d7d53ea6fa1d7fc Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 15 Nov 2018 12:05:06 -0600 Subject: [PATCH 135/167] - Added Discordant Dirge. Urza's Saga Set 100% done. --- .../src/mage/cards/d/DiscordantDirge.java | 99 +++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 1 + 2 files changed, 100 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DiscordantDirge.java diff --git a/Mage.Sets/src/mage/cards/d/DiscordantDirge.java b/Mage.Sets/src/mage/cards/d/DiscordantDirge.java new file mode 100644 index 0000000000..cab74cb987 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DiscordantDirge.java @@ -0,0 +1,99 @@ +package mage.cards.d; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; + +/** + * + * @author jeffwadsworth + */ +public final class DiscordantDirge extends CardImpl { + + private static final String rule = "Look at target opponent's hand and choose up to X cards from it, where X is the number of verse counters on {this}. That player discards those cards.."; + + public DiscordantDirge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); + + // At the beginning of your upkeep, you may put a verse counter on Discordant Dirge. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.VERSE.createInstance(), true), TargetController.YOU, true)); + + // {B}, Sacrifice Discordant Dirge: Look at target opponent's hand and choose up to X cards from it, where X is the number of verse counters on Discordant Dirge. That player discards those cards. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DiscordantDirgeEffect(), + new ManaCostsImpl("{B}")); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public DiscordantDirge(final DiscordantDirge card) { + super(card); + } + + @Override + public DiscordantDirge copy() { + return new DiscordantDirge(this); + } +} + +class DiscordantDirgeEffect extends OneShotEffect { + + public DiscordantDirgeEffect() { + super(Outcome.Benefit); + staticText = "Look at target opponent's hand and choose up to X cards from it, where X is the number of verse counters on {this}. That player discards those card."; + } + + public DiscordantDirgeEffect(final DiscordantDirgeEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent discordantDirge = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (discordantDirge != null) { + int verseCounters = discordantDirge.getCounters(game).getCount(CounterType.VERSE); + Player targetOpponent = game.getPlayer(source.getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + if (targetOpponent != null + && controller != null) { + controller.lookAtCards(targetOpponent.getName() + " hand", targetOpponent.getHand(), game); + TargetCard target = new TargetCard(0, verseCounters, Zone.HAND, new FilterCard()); + target.setNotTarget(true); + if (controller.choose(Outcome.Benefit, targetOpponent.getHand(), target, game)) { + target.getTargets().stream().map((targetCardId) -> game.getCard(targetCardId)).filter((card) -> (card != null + && targetOpponent.getHand().contains(card.getId()))).forEachOrdered((card) -> { + targetOpponent.discard(card, source, game); + }); + return true; + } + } + } + return false; + } + + @Override + public DiscordantDirgeEffect copy() { + return new DiscordantDirgeEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index e9122c12f5..ab0632ed8e 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -98,6 +98,7 @@ public final class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Diabolic Servitude", 130, Rarity.UNCOMMON, mage.cards.d.DiabolicServitude.class)); cards.add(new SetCardInfo("Disciple of Grace", 10, Rarity.COMMON, mage.cards.d.DiscipleOfGrace.class)); cards.add(new SetCardInfo("Disciple of Law", 11, Rarity.COMMON, mage.cards.d.DiscipleOfLaw.class)); + cards.add(new SetCardInfo("Discordant Dirge", 131, Rarity.RARE, mage.cards.d.DiscordantDirge.class)); cards.add(new SetCardInfo("Disenchant", 12, Rarity.COMMON, mage.cards.d.Disenchant.class)); cards.add(new SetCardInfo("Disorder", 181, Rarity.UNCOMMON, mage.cards.d.Disorder.class)); cards.add(new SetCardInfo("Disruptive Student", 69, Rarity.COMMON, mage.cards.d.DisruptiveStudent.class)); From fab9a794434b0495c360c8a4db35097ed6eaf2e6 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 15 Nov 2018 19:09:23 -0600 Subject: [PATCH 136/167] - Added Viashino Bey, Lurking Skirge, and Opal Avenger. Urza's Legacy Set 100% done. --- Mage.Sets/src/mage/cards/l/LurkingSkirge.java | 71 ++++ Mage.Sets/src/mage/cards/o/OpalAvenger.java | 120 ++++++ Mage.Sets/src/mage/cards/v/VeiledSentry.java | 1 + Mage.Sets/src/mage/cards/v/ViashinoBey.java | 92 +++++ Mage.Sets/src/mage/sets/UrzasLegacy.java | 347 +++++++++--------- 5 files changed, 459 insertions(+), 172 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/l/LurkingSkirge.java create mode 100644 Mage.Sets/src/mage/cards/o/OpalAvenger.java create mode 100644 Mage.Sets/src/mage/cards/v/ViashinoBey.java diff --git a/Mage.Sets/src/mage/cards/l/LurkingSkirge.java b/Mage.Sets/src/mage/cards/l/LurkingSkirge.java new file mode 100644 index 0000000000..8829e559b7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LurkingSkirge.java @@ -0,0 +1,71 @@ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.other.OwnerPredicate; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class LurkingSkirge extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new OwnerPredicate(TargetController.OPPONENT)); + } + + public LurkingSkirge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); + + // When a creature is put into an opponent's graveyard from the battlefield, if Lurking Skirge is an enchantment, Lurking Skirge becomes a 3/2 Imp creature with flying. + TriggeredAbility ability = new PutIntoGraveFromBattlefieldAllTriggeredAbility(new BecomesCreatureSourceEffect(new LurkingSkirgeToken(), "", Duration.WhileOnBattlefield, true, false), false, filter, false); + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_ENCHANTMENT_PERMANENT), + "When a creature is put into an opponent's graveyard from the battlefield, if {this} is an enchantment, {this} becomes a 3/2 Imp creature with flying.")); + } + + public LurkingSkirge(final LurkingSkirge card) { + super(card); + } + + @Override + public LurkingSkirge copy() { + return new LurkingSkirge(this); + } +} + +class LurkingSkirgeToken extends TokenImpl { + + public LurkingSkirgeToken() { + super("Imp", "3/2 Imp with flying."); + cardType.add(CardType.CREATURE); + subtype.add(SubType.IMP); + power = new MageInt(3); + toughness = new MageInt(2); + this.addAbility(FlyingAbility.getInstance()); + } + + public LurkingSkirgeToken(final LurkingSkirgeToken token) { + super(token); + } + + public LurkingSkirgeToken copy() { + return new LurkingSkirgeToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OpalAvenger.java b/Mage.Sets/src/mage/cards/o/OpalAvenger.java new file mode 100644 index 0000000000..5586cbedf6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OpalAvenger.java @@ -0,0 +1,120 @@ +package mage.cards.o; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +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.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class OpalAvenger extends CardImpl { + + public OpalAvenger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + + // When you have 10 or less life, if Opal Avenger is an enchantment, Opal Avenger becomes a 3/5 Soldier creature. + this.addAbility(new OpalAvengerStateTriggeredAbility()); + } + + public OpalAvenger(final OpalAvenger card) { + super(card); + } + + @Override + public OpalAvenger copy() { + return new OpalAvenger(this); + } +} + +class OpalAvengerStateTriggeredAbility extends StateTriggeredAbility { + + public OpalAvengerStateTriggeredAbility() { + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new OpalAvengerToken(), "", Duration.Custom, true, false)); + } + + public OpalAvengerStateTriggeredAbility(final OpalAvengerStateTriggeredAbility ability) { + super(ability); + } + + @Override + public OpalAvengerStateTriggeredAbility copy() { + return new OpalAvengerStateTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return game.getState().getPlayer(getControllerId()).getLife() <= 10; + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + } + + @Override + public boolean canTrigger(Game game) { + //20100716 - 603.8 + Boolean triggered = (Boolean) game.getState().getValue(getSourceId().toString() + "triggered"); + if (triggered == null) { + triggered = Boolean.FALSE; + } + return !triggered; + } + + @Override + public void trigger(Game game, UUID controllerId) { + //20100716 - 603.8 + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE); + super.trigger(game, controllerId); + } + + @Override + public boolean resolve(Game game) { + //20100716 - 603.8 + boolean result = super.resolve(game); + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + return result; + } + + @Override + public void counter(Game game) { + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + } + + @Override + public String getRule() { + return new StringBuilder("When you have 10 or less life, if {this} is an enchantment, ").append(super.getRule()).toString(); + } + +} + +class OpalAvengerToken extends TokenImpl { + + public OpalAvengerToken() { + super("Soldier", "3/5 Soldier creature"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.SOLDIER); + power = new MageInt(3); + toughness = new MageInt(5); + } + + public OpalAvengerToken(final OpalAvengerToken token) { + super(token); + } + + @Override + public OpalAvengerToken copy() { + return new OpalAvengerToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VeiledSentry.java b/Mage.Sets/src/mage/cards/v/VeiledSentry.java index 8c79053975..3c6ce6f61e 100644 --- a/Mage.Sets/src/mage/cards/v/VeiledSentry.java +++ b/Mage.Sets/src/mage/cards/v/VeiledSentry.java @@ -80,6 +80,7 @@ class VeiledSentryEffect extends ContinuousEffectImpl { switch (layer) { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { + veiledSentry.getCardType().clear(); if (!veiledSentry.isCreature()) { veiledSentry.addCardType(CardType.CREATURE); } diff --git a/Mage.Sets/src/mage/cards/v/ViashinoBey.java b/Mage.Sets/src/mage/cards/v/ViashinoBey.java new file mode 100644 index 0000000000..e0a3e05bd1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/ViashinoBey.java @@ -0,0 +1,92 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author jeffwadsworth + */ +public final class ViashinoBey extends CardImpl { + + private static final String rule = "If {this} attacks, all creatures you control attack if able."; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public ViashinoBey(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + + this.subtype.add(SubType.VIASHINO); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // If Viashino Bey attacks, all creatures you control attack if able. + this.addAbility(new AttacksTriggeredAbility(new ViashinoBeyEffect(), false, rule)); + + } + + public ViashinoBey(final ViashinoBey card) { + super(card); + } + + @Override + public ViashinoBey copy() { + return new ViashinoBey(this); + } +} + +class ViashinoBeyEffect extends OneShotEffect { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public ViashinoBeyEffect() { + super(Outcome.Benefit); + } + + public ViashinoBeyEffect(final ViashinoBeyEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + TargetOpponent targetDefender = new TargetOpponent(); + if (controller != null) { + game.getBattlefield().getAllActivePermanents(CardType.CREATURE).stream().filter((permanent) -> (filter.match(permanent, source.getSourceId(), source.getControllerId(), game))).forEachOrdered((permanent) -> { + if (game.getOpponents(controller.getId()).size() > 1) { + controller.choose(outcome.Benefit, targetDefender, source.getSourceId(), game); + } else { + targetDefender.add(game.getOpponents(controller.getId()).iterator().next(), game); + } + controller.declareAttacker(permanent.getId(), targetDefender.getFirstTarget(), game, false); + }); + } + return false; + } + + @Override + public ViashinoBeyEffect copy() { + return new ViashinoBeyEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasLegacy.java b/Mage.Sets/src/mage/sets/UrzasLegacy.java index eaa00b8c3c..431d2eb3f8 100644 --- a/Mage.Sets/src/mage/sets/UrzasLegacy.java +++ b/Mage.Sets/src/mage/sets/UrzasLegacy.java @@ -1,172 +1,175 @@ - -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author noxx - */ -public final class UrzasLegacy extends ExpansionSet { - - private static final UrzasLegacy instance = new UrzasLegacy(); - - public static UrzasLegacy getInstance() { - return instance; - } - - private UrzasLegacy() { - super("Urza's Legacy", "ULG", ExpansionSet.buildDate(1999, 2, 15), SetType.EXPANSION); - this.blockName = "Urza"; - this.parentSet = UrzasSaga.getInstance(); - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("About Face", 73, Rarity.COMMON, mage.cards.a.AboutFace.class)); - cards.add(new SetCardInfo("Angel's Trumpet", 121, Rarity.UNCOMMON, mage.cards.a.AngelsTrumpet.class)); - cards.add(new SetCardInfo("Angelic Curator", 1, Rarity.COMMON, mage.cards.a.AngelicCurator.class)); - cards.add(new SetCardInfo("Anthroplasm", 25, Rarity.RARE, mage.cards.a.Anthroplasm.class)); - cards.add(new SetCardInfo("Archivist", 26, Rarity.RARE, mage.cards.a.Archivist.class)); - cards.add(new SetCardInfo("Aura Flux", 27, Rarity.COMMON, mage.cards.a.AuraFlux.class)); - cards.add(new SetCardInfo("Avalanche Riders", 74, Rarity.UNCOMMON, mage.cards.a.AvalancheRiders.class)); - cards.add(new SetCardInfo("Beast of Burden", 122, Rarity.RARE, mage.cards.b.BeastOfBurden.class)); - cards.add(new SetCardInfo("Blessed Reversal", 2, Rarity.RARE, mage.cards.b.BlessedReversal.class)); - cards.add(new SetCardInfo("Bloated Toad", 97, Rarity.UNCOMMON, mage.cards.b.BloatedToad.class)); - cards.add(new SetCardInfo("Bone Shredder", 49, Rarity.UNCOMMON, mage.cards.b.BoneShredder.class)); - cards.add(new SetCardInfo("Bouncing Beebles", 28, Rarity.COMMON, mage.cards.b.BouncingBeebles.class)); - cards.add(new SetCardInfo("Brink of Madness", 50, Rarity.RARE, mage.cards.b.BrinkOfMadness.class)); - cards.add(new SetCardInfo("Burst of Energy", 3, Rarity.COMMON, mage.cards.b.BurstOfEnergy.class)); - cards.add(new SetCardInfo("Cessation", 4, Rarity.COMMON, mage.cards.c.Cessation.class)); - cards.add(new SetCardInfo("Cloud of Faeries", 29, Rarity.COMMON, mage.cards.c.CloudOfFaeries.class)); - cards.add(new SetCardInfo("Crawlspace", 123, Rarity.RARE, mage.cards.c.Crawlspace.class)); - cards.add(new SetCardInfo("Crop Rotation", 98, Rarity.COMMON, mage.cards.c.CropRotation.class)); - cards.add(new SetCardInfo("Damping Engine", 124, Rarity.RARE, mage.cards.d.DampingEngine.class)); - cards.add(new SetCardInfo("Darkwatch Elves", 99, Rarity.UNCOMMON, mage.cards.d.DarkwatchElves.class)); - cards.add(new SetCardInfo("Defender of Chaos", 75, Rarity.COMMON, mage.cards.d.DefenderOfChaos.class)); - cards.add(new SetCardInfo("Defender of Law", 5, Rarity.COMMON, mage.cards.d.DefenderOfLaw.class)); - cards.add(new SetCardInfo("Defense Grid", 125, Rarity.RARE, mage.cards.d.DefenseGrid.class)); - cards.add(new SetCardInfo("Defense of the Heart", 100, Rarity.RARE, mage.cards.d.DefenseOfTheHeart.class)); - cards.add(new SetCardInfo("Delusions of Mediocrity", 30, Rarity.RARE, mage.cards.d.DelusionsOfMediocrity.class)); - cards.add(new SetCardInfo("Deranged Hermit", 101, Rarity.RARE, mage.cards.d.DerangedHermit.class)); - cards.add(new SetCardInfo("Devout Harpist", 6, Rarity.COMMON, mage.cards.d.DevoutHarpist.class)); - cards.add(new SetCardInfo("Engineered Plague", 51, Rarity.UNCOMMON, mage.cards.e.EngineeredPlague.class)); - cards.add(new SetCardInfo("Erase", 7, Rarity.COMMON, mage.cards.e.Erase.class)); - cards.add(new SetCardInfo("Eviscerator", 52, Rarity.RARE, mage.cards.e.Eviscerator.class)); - cards.add(new SetCardInfo("Expendable Troops", 8, Rarity.COMMON, mage.cards.e.ExpendableTroops.class)); - cards.add(new SetCardInfo("Faerie Conclave", 139, Rarity.UNCOMMON, mage.cards.f.FaerieConclave.class)); - cards.add(new SetCardInfo("Fleeting Image", 31, Rarity.RARE, mage.cards.f.FleetingImage.class)); - cards.add(new SetCardInfo("Fog of Gnats", 53, Rarity.COMMON, mage.cards.f.FogOfGnats.class)); - cards.add(new SetCardInfo("Forbidding Watchtower", 140, Rarity.UNCOMMON, mage.cards.f.ForbiddingWatchtower.class)); - cards.add(new SetCardInfo("Frantic Search", 32, Rarity.COMMON, mage.cards.f.FranticSearch.class)); - cards.add(new SetCardInfo("Gang of Elk", 102, Rarity.UNCOMMON, mage.cards.g.GangOfElk.class)); - cards.add(new SetCardInfo("Ghitu Encampment", 141, Rarity.UNCOMMON, mage.cards.g.GhituEncampment.class)); - cards.add(new SetCardInfo("Ghitu Fire-Eater", 76, Rarity.UNCOMMON, mage.cards.g.GhituFireEater.class)); - cards.add(new SetCardInfo("Ghitu Slinger", 77, Rarity.COMMON, mage.cards.g.GhituSlinger.class)); - cards.add(new SetCardInfo("Ghitu War Cry", 78, Rarity.UNCOMMON, mage.cards.g.GhituWarCry.class)); - cards.add(new SetCardInfo("Giant Cockroach", 54, Rarity.COMMON, mage.cards.g.GiantCockroach.class)); - cards.add(new SetCardInfo("Goblin Medics", 79, Rarity.COMMON, mage.cards.g.GoblinMedics.class)); - cards.add(new SetCardInfo("Goblin Welder", 80, Rarity.RARE, mage.cards.g.GoblinWelder.class)); - cards.add(new SetCardInfo("Granite Grip", 81, Rarity.COMMON, mage.cards.g.GraniteGrip.class)); - cards.add(new SetCardInfo("Grim Monolith", 126, Rarity.RARE, mage.cards.g.GrimMonolith.class)); - cards.add(new SetCardInfo("Harmonic Convergence", 103, Rarity.UNCOMMON, mage.cards.h.HarmonicConvergence.class)); - cards.add(new SetCardInfo("Hidden Gibbons", 104, Rarity.RARE, mage.cards.h.HiddenGibbons.class)); - cards.add(new SetCardInfo("Hope and Glory", 9, Rarity.UNCOMMON, mage.cards.h.HopeAndGlory.class)); - cards.add(new SetCardInfo("Impending Disaster", 82, Rarity.RARE, mage.cards.i.ImpendingDisaster.class)); - cards.add(new SetCardInfo("Intervene", 33, Rarity.COMMON, mage.cards.i.Intervene.class)); - cards.add(new SetCardInfo("Iron Maiden", 127, Rarity.RARE, mage.cards.i.IronMaiden.class)); - cards.add(new SetCardInfo("Iron Will", 10, Rarity.COMMON, mage.cards.i.IronWill.class)); - cards.add(new SetCardInfo("Jhoira's Toolbox", 128, Rarity.UNCOMMON, mage.cards.j.JhoirasToolbox.class)); - cards.add(new SetCardInfo("Karmic Guide", 11, Rarity.RARE, mage.cards.k.KarmicGuide.class)); - cards.add(new SetCardInfo("King Crab", 34, Rarity.UNCOMMON, mage.cards.k.KingCrab.class)); - cards.add(new SetCardInfo("Knighthood", 12, Rarity.UNCOMMON, mage.cards.k.Knighthood.class)); - cards.add(new SetCardInfo("Last-Ditch Effort", 83, Rarity.UNCOMMON, mage.cards.l.LastDitchEffort.class)); - cards.add(new SetCardInfo("Lava Axe", 84, Rarity.COMMON, mage.cards.l.LavaAxe.class)); - cards.add(new SetCardInfo("Levitation", 35, Rarity.UNCOMMON, mage.cards.l.Levitation.class)); - cards.add(new SetCardInfo("Lone Wolf", 105, Rarity.UNCOMMON, mage.cards.l.LoneWolf.class)); - cards.add(new SetCardInfo("Martyr's Cause", 13, Rarity.UNCOMMON, mage.cards.m.MartyrsCause.class)); - cards.add(new SetCardInfo("Memory Jar", 129, Rarity.RARE, mage.cards.m.MemoryJar.class)); - cards.add(new SetCardInfo("Might of Oaks", 106, Rarity.RARE, mage.cards.m.MightOfOaks.class)); - cards.add(new SetCardInfo("Miscalculation", 36, Rarity.COMMON, mage.cards.m.Miscalculation.class)); - cards.add(new SetCardInfo("Molten Hydra", 85, Rarity.RARE, mage.cards.m.MoltenHydra.class)); - cards.add(new SetCardInfo("Mother of Runes", 14, Rarity.UNCOMMON, mage.cards.m.MotherOfRunes.class)); - cards.add(new SetCardInfo("Multani's Acolyte", 108, Rarity.COMMON, mage.cards.m.MultanisAcolyte.class)); - cards.add(new SetCardInfo("Multani's Presence", 109, Rarity.UNCOMMON, mage.cards.m.MultanisPresence.class)); - cards.add(new SetCardInfo("Multani, Maro-Sorcerer", 107, Rarity.RARE, mage.cards.m.MultaniMaroSorcerer.class)); - cards.add(new SetCardInfo("No Mercy", 56, Rarity.RARE, mage.cards.n.NoMercy.class)); - cards.add(new SetCardInfo("Opal Champion", 16, Rarity.COMMON, mage.cards.o.OpalChampion.class)); - cards.add(new SetCardInfo("Opportunity", 37, Rarity.UNCOMMON, mage.cards.o.Opportunity.class)); - cards.add(new SetCardInfo("Ostracize", 57, Rarity.COMMON, mage.cards.o.Ostracize.class)); - cards.add(new SetCardInfo("Palinchron", 38, Rarity.RARE, mage.cards.p.Palinchron.class)); - cards.add(new SetCardInfo("Parch", 86, Rarity.COMMON, mage.cards.p.Parch.class)); - cards.add(new SetCardInfo("Peace and Quiet", 17, Rarity.UNCOMMON, mage.cards.p.PeaceAndQuiet.class)); - cards.add(new SetCardInfo("Phyrexian Broodlings", 58, Rarity.COMMON, mage.cards.p.PhyrexianBroodlings.class)); - cards.add(new SetCardInfo("Phyrexian Debaser", 59, Rarity.COMMON, mage.cards.p.PhyrexianDebaser.class)); - cards.add(new SetCardInfo("Phyrexian Defiler", 60, Rarity.UNCOMMON, mage.cards.p.PhyrexianDefiler.class)); - cards.add(new SetCardInfo("Phyrexian Denouncer", 61, Rarity.COMMON, mage.cards.p.PhyrexianDenouncer.class)); - cards.add(new SetCardInfo("Phyrexian Plaguelord", 62, Rarity.RARE, mage.cards.p.PhyrexianPlaguelord.class)); - cards.add(new SetCardInfo("Phyrexian Reclamation", 63, Rarity.UNCOMMON, mage.cards.p.PhyrexianReclamation.class)); - cards.add(new SetCardInfo("Plague Beetle", 64, Rarity.COMMON, mage.cards.p.PlagueBeetle.class)); - cards.add(new SetCardInfo("Planar Collapse", 18, Rarity.RARE, mage.cards.p.PlanarCollapse.class)); - cards.add(new SetCardInfo("Purify", 19, Rarity.RARE, mage.cards.p.Purify.class)); - cards.add(new SetCardInfo("Pygmy Pyrosaur", 87, Rarity.COMMON, mage.cards.p.PygmyPyrosaur.class)); - cards.add(new SetCardInfo("Pyromancy", 88, Rarity.RARE, mage.cards.p.Pyromancy.class)); - cards.add(new SetCardInfo("Quicksilver Amulet", 130, Rarity.RARE, mage.cards.q.QuicksilverAmulet.class)); - cards.add(new SetCardInfo("Rack and Ruin", 89, Rarity.UNCOMMON, mage.cards.r.RackAndRuin.class)); - cards.add(new SetCardInfo("Radiant's Dragoons", 21, Rarity.UNCOMMON, mage.cards.r.RadiantsDragoons.class)); - cards.add(new SetCardInfo("Radiant's Judgment", 22, Rarity.COMMON, mage.cards.r.RadiantsJudgment.class)); - cards.add(new SetCardInfo("Radiant, Archangel", 20, Rarity.RARE, mage.cards.r.RadiantArchangel.class)); - cards.add(new SetCardInfo("Rancor", 110, Rarity.COMMON, mage.cards.r.Rancor.class)); - cards.add(new SetCardInfo("Rank and File", 65, Rarity.UNCOMMON, mage.cards.r.RankAndFile.class)); - cards.add(new SetCardInfo("Raven Familiar", 39, Rarity.UNCOMMON, mage.cards.r.RavenFamiliar.class)); - cards.add(new SetCardInfo("Rebuild", 40, Rarity.UNCOMMON, mage.cards.r.Rebuild.class)); - cards.add(new SetCardInfo("Repopulate", 111, Rarity.COMMON, mage.cards.r.Repopulate.class)); - cards.add(new SetCardInfo("Ring of Gix", 131, Rarity.RARE, mage.cards.r.RingOfGix.class)); - cards.add(new SetCardInfo("Rivalry", 90, Rarity.RARE, mage.cards.r.Rivalry.class)); - cards.add(new SetCardInfo("Scrapheap", 132, Rarity.RARE, mage.cards.s.Scrapheap.class)); - cards.add(new SetCardInfo("Second Chance", 41, Rarity.RARE, mage.cards.s.SecondChance.class)); - cards.add(new SetCardInfo("Shivan Phoenix", 91, Rarity.RARE, mage.cards.s.ShivanPhoenix.class)); - cards.add(new SetCardInfo("Sick and Tired", 66, Rarity.COMMON, mage.cards.s.SickAndTired.class)); - cards.add(new SetCardInfo("Silk Net", 112, Rarity.COMMON, mage.cards.s.SilkNet.class)); - cards.add(new SetCardInfo("Simian Grunts", 113, Rarity.COMMON, mage.cards.s.SimianGrunts.class)); - cards.add(new SetCardInfo("Sleeper's Guile", 67, Rarity.COMMON, mage.cards.s.SleepersGuile.class)); - cards.add(new SetCardInfo("Slow Motion", 42, Rarity.COMMON, mage.cards.s.SlowMotion.class)); - cards.add(new SetCardInfo("Sluggishness", 92, Rarity.COMMON, mage.cards.s.Sluggishness.class)); - cards.add(new SetCardInfo("Snap", 43, Rarity.COMMON, mage.cards.s.Snap.class)); - cards.add(new SetCardInfo("Spawning Pool", 142, Rarity.UNCOMMON, mage.cards.s.SpawningPool.class)); - cards.add(new SetCardInfo("Subversion", 68, Rarity.RARE, mage.cards.s.Subversion.class)); - cards.add(new SetCardInfo("Sustainer of the Realm", 23, Rarity.UNCOMMON, mage.cards.s.SustainerOfTheRealm.class)); - cards.add(new SetCardInfo("Swat", 69, Rarity.COMMON, mage.cards.s.Swat.class)); - cards.add(new SetCardInfo("Tethered Skirge", 70, Rarity.UNCOMMON, mage.cards.t.TetheredSkirge.class)); - cards.add(new SetCardInfo("Thornwind Faeries", 44, Rarity.COMMON, mage.cards.t.ThornwindFaeries.class)); - cards.add(new SetCardInfo("Thran Lens", 133, Rarity.RARE, mage.cards.t.ThranLens.class)); - cards.add(new SetCardInfo("Thran War Machine", 134, Rarity.UNCOMMON, mage.cards.t.ThranWarMachine.class)); - cards.add(new SetCardInfo("Thran Weaponry", 135, Rarity.RARE, mage.cards.t.ThranWeaponry.class)); - cards.add(new SetCardInfo("Ticking Gnomes", 136, Rarity.UNCOMMON, mage.cards.t.TickingGnomes.class)); - cards.add(new SetCardInfo("Tinker", 45, Rarity.UNCOMMON, mage.cards.t.Tinker.class)); - cards.add(new SetCardInfo("Tragic Poet", 24, Rarity.COMMON, mage.cards.t.TragicPoet.class)); - cards.add(new SetCardInfo("Treacherous Link", 71, Rarity.UNCOMMON, mage.cards.t.TreacherousLink.class)); - cards.add(new SetCardInfo("Treefolk Mystic", 114, Rarity.COMMON, mage.cards.t.TreefolkMystic.class)); - cards.add(new SetCardInfo("Treetop Village", 143, Rarity.UNCOMMON, mage.cards.t.TreetopVillage.class)); - cards.add(new SetCardInfo("Unearth", 72, Rarity.COMMON, mage.cards.u.Unearth.class)); - cards.add(new SetCardInfo("Urza's Blueprints", 137, Rarity.RARE, mage.cards.u.UrzasBlueprints.class)); - cards.add(new SetCardInfo("Viashino Cutthroat", 94, Rarity.UNCOMMON, mage.cards.v.ViashinoCutthroat.class)); - cards.add(new SetCardInfo("Viashino Heretic", 95, Rarity.UNCOMMON, mage.cards.v.ViashinoHeretic.class)); - cards.add(new SetCardInfo("Viashino Sandscout", 96, Rarity.COMMON, mage.cards.v.ViashinoSandscout.class)); - cards.add(new SetCardInfo("Vigilant Drake", 46, Rarity.COMMON, mage.cards.v.VigilantDrake.class)); - cards.add(new SetCardInfo("Walking Sponge", 47, Rarity.UNCOMMON, mage.cards.w.WalkingSponge.class)); - cards.add(new SetCardInfo("Weatherseed Elf", 115, Rarity.COMMON, mage.cards.w.WeatherseedElf.class)); - cards.add(new SetCardInfo("Weatherseed Faeries", 48, Rarity.COMMON, mage.cards.w.WeatherseedFaeries.class)); - cards.add(new SetCardInfo("Weatherseed Treefolk", 116, Rarity.RARE, mage.cards.w.WeatherseedTreefolk.class)); - cards.add(new SetCardInfo("Wheel of Torture", 138, Rarity.RARE, mage.cards.w.WheelOfTorture.class)); - cards.add(new SetCardInfo("Wing Snare", 117, Rarity.UNCOMMON, mage.cards.w.WingSnare.class)); - cards.add(new SetCardInfo("Yavimaya Granger", 118, Rarity.COMMON, mage.cards.y.YavimayaGranger.class)); - cards.add(new SetCardInfo("Yavimaya Scion", 119, Rarity.COMMON, mage.cards.y.YavimayaScion.class)); - cards.add(new SetCardInfo("Yavimaya Wurm", 120, Rarity.COMMON, mage.cards.y.YavimayaWurm.class)); - } -} + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author noxx + */ +public final class UrzasLegacy extends ExpansionSet { + + private static final UrzasLegacy instance = new UrzasLegacy(); + + public static UrzasLegacy getInstance() { + return instance; + } + + private UrzasLegacy() { + super("Urza's Legacy", "ULG", ExpansionSet.buildDate(1999, 2, 15), SetType.EXPANSION); + this.blockName = "Urza"; + this.parentSet = UrzasSaga.getInstance(); + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("About Face", 73, Rarity.COMMON, mage.cards.a.AboutFace.class)); + cards.add(new SetCardInfo("Angel's Trumpet", 121, Rarity.UNCOMMON, mage.cards.a.AngelsTrumpet.class)); + cards.add(new SetCardInfo("Angelic Curator", 1, Rarity.COMMON, mage.cards.a.AngelicCurator.class)); + cards.add(new SetCardInfo("Anthroplasm", 25, Rarity.RARE, mage.cards.a.Anthroplasm.class)); + cards.add(new SetCardInfo("Archivist", 26, Rarity.RARE, mage.cards.a.Archivist.class)); + cards.add(new SetCardInfo("Aura Flux", 27, Rarity.COMMON, mage.cards.a.AuraFlux.class)); + cards.add(new SetCardInfo("Avalanche Riders", 74, Rarity.UNCOMMON, mage.cards.a.AvalancheRiders.class)); + cards.add(new SetCardInfo("Beast of Burden", 122, Rarity.RARE, mage.cards.b.BeastOfBurden.class)); + cards.add(new SetCardInfo("Blessed Reversal", 2, Rarity.RARE, mage.cards.b.BlessedReversal.class)); + cards.add(new SetCardInfo("Bloated Toad", 97, Rarity.UNCOMMON, mage.cards.b.BloatedToad.class)); + cards.add(new SetCardInfo("Bone Shredder", 49, Rarity.UNCOMMON, mage.cards.b.BoneShredder.class)); + cards.add(new SetCardInfo("Bouncing Beebles", 28, Rarity.COMMON, mage.cards.b.BouncingBeebles.class)); + cards.add(new SetCardInfo("Brink of Madness", 50, Rarity.RARE, mage.cards.b.BrinkOfMadness.class)); + cards.add(new SetCardInfo("Burst of Energy", 3, Rarity.COMMON, mage.cards.b.BurstOfEnergy.class)); + cards.add(new SetCardInfo("Cessation", 4, Rarity.COMMON, mage.cards.c.Cessation.class)); + cards.add(new SetCardInfo("Cloud of Faeries", 29, Rarity.COMMON, mage.cards.c.CloudOfFaeries.class)); + cards.add(new SetCardInfo("Crawlspace", 123, Rarity.RARE, mage.cards.c.Crawlspace.class)); + cards.add(new SetCardInfo("Crop Rotation", 98, Rarity.COMMON, mage.cards.c.CropRotation.class)); + cards.add(new SetCardInfo("Damping Engine", 124, Rarity.RARE, mage.cards.d.DampingEngine.class)); + cards.add(new SetCardInfo("Darkwatch Elves", 99, Rarity.UNCOMMON, mage.cards.d.DarkwatchElves.class)); + cards.add(new SetCardInfo("Defender of Chaos", 75, Rarity.COMMON, mage.cards.d.DefenderOfChaos.class)); + cards.add(new SetCardInfo("Defender of Law", 5, Rarity.COMMON, mage.cards.d.DefenderOfLaw.class)); + cards.add(new SetCardInfo("Defense Grid", 125, Rarity.RARE, mage.cards.d.DefenseGrid.class)); + cards.add(new SetCardInfo("Defense of the Heart", 100, Rarity.RARE, mage.cards.d.DefenseOfTheHeart.class)); + cards.add(new SetCardInfo("Delusions of Mediocrity", 30, Rarity.RARE, mage.cards.d.DelusionsOfMediocrity.class)); + cards.add(new SetCardInfo("Deranged Hermit", 101, Rarity.RARE, mage.cards.d.DerangedHermit.class)); + cards.add(new SetCardInfo("Devout Harpist", 6, Rarity.COMMON, mage.cards.d.DevoutHarpist.class)); + cards.add(new SetCardInfo("Engineered Plague", 51, Rarity.UNCOMMON, mage.cards.e.EngineeredPlague.class)); + cards.add(new SetCardInfo("Erase", 7, Rarity.COMMON, mage.cards.e.Erase.class)); + cards.add(new SetCardInfo("Eviscerator", 52, Rarity.RARE, mage.cards.e.Eviscerator.class)); + cards.add(new SetCardInfo("Expendable Troops", 8, Rarity.COMMON, mage.cards.e.ExpendableTroops.class)); + cards.add(new SetCardInfo("Faerie Conclave", 139, Rarity.UNCOMMON, mage.cards.f.FaerieConclave.class)); + cards.add(new SetCardInfo("Fleeting Image", 31, Rarity.RARE, mage.cards.f.FleetingImage.class)); + cards.add(new SetCardInfo("Fog of Gnats", 53, Rarity.COMMON, mage.cards.f.FogOfGnats.class)); + cards.add(new SetCardInfo("Forbidding Watchtower", 140, Rarity.UNCOMMON, mage.cards.f.ForbiddingWatchtower.class)); + cards.add(new SetCardInfo("Frantic Search", 32, Rarity.COMMON, mage.cards.f.FranticSearch.class)); + cards.add(new SetCardInfo("Gang of Elk", 102, Rarity.UNCOMMON, mage.cards.g.GangOfElk.class)); + cards.add(new SetCardInfo("Ghitu Encampment", 141, Rarity.UNCOMMON, mage.cards.g.GhituEncampment.class)); + cards.add(new SetCardInfo("Ghitu Fire-Eater", 76, Rarity.UNCOMMON, mage.cards.g.GhituFireEater.class)); + cards.add(new SetCardInfo("Ghitu Slinger", 77, Rarity.COMMON, mage.cards.g.GhituSlinger.class)); + cards.add(new SetCardInfo("Ghitu War Cry", 78, Rarity.UNCOMMON, mage.cards.g.GhituWarCry.class)); + cards.add(new SetCardInfo("Giant Cockroach", 54, Rarity.COMMON, mage.cards.g.GiantCockroach.class)); + cards.add(new SetCardInfo("Goblin Medics", 79, Rarity.COMMON, mage.cards.g.GoblinMedics.class)); + cards.add(new SetCardInfo("Goblin Welder", 80, Rarity.RARE, mage.cards.g.GoblinWelder.class)); + cards.add(new SetCardInfo("Granite Grip", 81, Rarity.COMMON, mage.cards.g.GraniteGrip.class)); + cards.add(new SetCardInfo("Grim Monolith", 126, Rarity.RARE, mage.cards.g.GrimMonolith.class)); + cards.add(new SetCardInfo("Harmonic Convergence", 103, Rarity.UNCOMMON, mage.cards.h.HarmonicConvergence.class)); + cards.add(new SetCardInfo("Hidden Gibbons", 104, Rarity.RARE, mage.cards.h.HiddenGibbons.class)); + cards.add(new SetCardInfo("Hope and Glory", 9, Rarity.UNCOMMON, mage.cards.h.HopeAndGlory.class)); + cards.add(new SetCardInfo("Impending Disaster", 82, Rarity.RARE, mage.cards.i.ImpendingDisaster.class)); + cards.add(new SetCardInfo("Intervene", 33, Rarity.COMMON, mage.cards.i.Intervene.class)); + cards.add(new SetCardInfo("Iron Maiden", 127, Rarity.RARE, mage.cards.i.IronMaiden.class)); + cards.add(new SetCardInfo("Iron Will", 10, Rarity.COMMON, mage.cards.i.IronWill.class)); + cards.add(new SetCardInfo("Jhoira's Toolbox", 128, Rarity.UNCOMMON, mage.cards.j.JhoirasToolbox.class)); + cards.add(new SetCardInfo("Karmic Guide", 11, Rarity.RARE, mage.cards.k.KarmicGuide.class)); + cards.add(new SetCardInfo("King Crab", 34, Rarity.UNCOMMON, mage.cards.k.KingCrab.class)); + cards.add(new SetCardInfo("Knighthood", 12, Rarity.UNCOMMON, mage.cards.k.Knighthood.class)); + cards.add(new SetCardInfo("Last-Ditch Effort", 83, Rarity.UNCOMMON, mage.cards.l.LastDitchEffort.class)); + cards.add(new SetCardInfo("Lava Axe", 84, Rarity.COMMON, mage.cards.l.LavaAxe.class)); + cards.add(new SetCardInfo("Levitation", 35, Rarity.UNCOMMON, mage.cards.l.Levitation.class)); + cards.add(new SetCardInfo("Lone Wolf", 105, Rarity.UNCOMMON, mage.cards.l.LoneWolf.class)); + cards.add(new SetCardInfo("Lurking Skirge", 55, Rarity.RARE, mage.cards.l.LurkingSkirge.class)); + cards.add(new SetCardInfo("Martyr's Cause", 13, Rarity.UNCOMMON, mage.cards.m.MartyrsCause.class)); + cards.add(new SetCardInfo("Memory Jar", 129, Rarity.RARE, mage.cards.m.MemoryJar.class)); + cards.add(new SetCardInfo("Might of Oaks", 106, Rarity.RARE, mage.cards.m.MightOfOaks.class)); + cards.add(new SetCardInfo("Miscalculation", 36, Rarity.COMMON, mage.cards.m.Miscalculation.class)); + cards.add(new SetCardInfo("Molten Hydra", 85, Rarity.RARE, mage.cards.m.MoltenHydra.class)); + cards.add(new SetCardInfo("Mother of Runes", 14, Rarity.UNCOMMON, mage.cards.m.MotherOfRunes.class)); + cards.add(new SetCardInfo("Multani's Acolyte", 108, Rarity.COMMON, mage.cards.m.MultanisAcolyte.class)); + cards.add(new SetCardInfo("Multani's Presence", 109, Rarity.UNCOMMON, mage.cards.m.MultanisPresence.class)); + cards.add(new SetCardInfo("Multani, Maro-Sorcerer", 107, Rarity.RARE, mage.cards.m.MultaniMaroSorcerer.class)); + cards.add(new SetCardInfo("No Mercy", 56, Rarity.RARE, mage.cards.n.NoMercy.class)); + cards.add(new SetCardInfo("Opal Avenger", 15, Rarity.RARE, mage.cards.o.OpalAvenger.class)); + cards.add(new SetCardInfo("Opal Champion", 16, Rarity.COMMON, mage.cards.o.OpalChampion.class)); + cards.add(new SetCardInfo("Opportunity", 37, Rarity.UNCOMMON, mage.cards.o.Opportunity.class)); + cards.add(new SetCardInfo("Ostracize", 57, Rarity.COMMON, mage.cards.o.Ostracize.class)); + cards.add(new SetCardInfo("Palinchron", 38, Rarity.RARE, mage.cards.p.Palinchron.class)); + cards.add(new SetCardInfo("Parch", 86, Rarity.COMMON, mage.cards.p.Parch.class)); + cards.add(new SetCardInfo("Peace and Quiet", 17, Rarity.UNCOMMON, mage.cards.p.PeaceAndQuiet.class)); + cards.add(new SetCardInfo("Phyrexian Broodlings", 58, Rarity.COMMON, mage.cards.p.PhyrexianBroodlings.class)); + cards.add(new SetCardInfo("Phyrexian Debaser", 59, Rarity.COMMON, mage.cards.p.PhyrexianDebaser.class)); + cards.add(new SetCardInfo("Phyrexian Defiler", 60, Rarity.UNCOMMON, mage.cards.p.PhyrexianDefiler.class)); + cards.add(new SetCardInfo("Phyrexian Denouncer", 61, Rarity.COMMON, mage.cards.p.PhyrexianDenouncer.class)); + cards.add(new SetCardInfo("Phyrexian Plaguelord", 62, Rarity.RARE, mage.cards.p.PhyrexianPlaguelord.class)); + cards.add(new SetCardInfo("Phyrexian Reclamation", 63, Rarity.UNCOMMON, mage.cards.p.PhyrexianReclamation.class)); + cards.add(new SetCardInfo("Plague Beetle", 64, Rarity.COMMON, mage.cards.p.PlagueBeetle.class)); + cards.add(new SetCardInfo("Planar Collapse", 18, Rarity.RARE, mage.cards.p.PlanarCollapse.class)); + cards.add(new SetCardInfo("Purify", 19, Rarity.RARE, mage.cards.p.Purify.class)); + cards.add(new SetCardInfo("Pygmy Pyrosaur", 87, Rarity.COMMON, mage.cards.p.PygmyPyrosaur.class)); + cards.add(new SetCardInfo("Pyromancy", 88, Rarity.RARE, mage.cards.p.Pyromancy.class)); + cards.add(new SetCardInfo("Quicksilver Amulet", 130, Rarity.RARE, mage.cards.q.QuicksilverAmulet.class)); + cards.add(new SetCardInfo("Rack and Ruin", 89, Rarity.UNCOMMON, mage.cards.r.RackAndRuin.class)); + cards.add(new SetCardInfo("Radiant's Dragoons", 21, Rarity.UNCOMMON, mage.cards.r.RadiantsDragoons.class)); + cards.add(new SetCardInfo("Radiant's Judgment", 22, Rarity.COMMON, mage.cards.r.RadiantsJudgment.class)); + cards.add(new SetCardInfo("Radiant, Archangel", 20, Rarity.RARE, mage.cards.r.RadiantArchangel.class)); + cards.add(new SetCardInfo("Rancor", 110, Rarity.COMMON, mage.cards.r.Rancor.class)); + cards.add(new SetCardInfo("Rank and File", 65, Rarity.UNCOMMON, mage.cards.r.RankAndFile.class)); + cards.add(new SetCardInfo("Raven Familiar", 39, Rarity.UNCOMMON, mage.cards.r.RavenFamiliar.class)); + cards.add(new SetCardInfo("Rebuild", 40, Rarity.UNCOMMON, mage.cards.r.Rebuild.class)); + cards.add(new SetCardInfo("Repopulate", 111, Rarity.COMMON, mage.cards.r.Repopulate.class)); + cards.add(new SetCardInfo("Ring of Gix", 131, Rarity.RARE, mage.cards.r.RingOfGix.class)); + cards.add(new SetCardInfo("Rivalry", 90, Rarity.RARE, mage.cards.r.Rivalry.class)); + cards.add(new SetCardInfo("Scrapheap", 132, Rarity.RARE, mage.cards.s.Scrapheap.class)); + cards.add(new SetCardInfo("Second Chance", 41, Rarity.RARE, mage.cards.s.SecondChance.class)); + cards.add(new SetCardInfo("Shivan Phoenix", 91, Rarity.RARE, mage.cards.s.ShivanPhoenix.class)); + cards.add(new SetCardInfo("Sick and Tired", 66, Rarity.COMMON, mage.cards.s.SickAndTired.class)); + cards.add(new SetCardInfo("Silk Net", 112, Rarity.COMMON, mage.cards.s.SilkNet.class)); + cards.add(new SetCardInfo("Simian Grunts", 113, Rarity.COMMON, mage.cards.s.SimianGrunts.class)); + cards.add(new SetCardInfo("Sleeper's Guile", 67, Rarity.COMMON, mage.cards.s.SleepersGuile.class)); + cards.add(new SetCardInfo("Slow Motion", 42, Rarity.COMMON, mage.cards.s.SlowMotion.class)); + cards.add(new SetCardInfo("Sluggishness", 92, Rarity.COMMON, mage.cards.s.Sluggishness.class)); + cards.add(new SetCardInfo("Snap", 43, Rarity.COMMON, mage.cards.s.Snap.class)); + cards.add(new SetCardInfo("Spawning Pool", 142, Rarity.UNCOMMON, mage.cards.s.SpawningPool.class)); + cards.add(new SetCardInfo("Subversion", 68, Rarity.RARE, mage.cards.s.Subversion.class)); + cards.add(new SetCardInfo("Sustainer of the Realm", 23, Rarity.UNCOMMON, mage.cards.s.SustainerOfTheRealm.class)); + cards.add(new SetCardInfo("Swat", 69, Rarity.COMMON, mage.cards.s.Swat.class)); + cards.add(new SetCardInfo("Tethered Skirge", 70, Rarity.UNCOMMON, mage.cards.t.TetheredSkirge.class)); + cards.add(new SetCardInfo("Thornwind Faeries", 44, Rarity.COMMON, mage.cards.t.ThornwindFaeries.class)); + cards.add(new SetCardInfo("Thran Lens", 133, Rarity.RARE, mage.cards.t.ThranLens.class)); + cards.add(new SetCardInfo("Thran War Machine", 134, Rarity.UNCOMMON, mage.cards.t.ThranWarMachine.class)); + cards.add(new SetCardInfo("Thran Weaponry", 135, Rarity.RARE, mage.cards.t.ThranWeaponry.class)); + cards.add(new SetCardInfo("Ticking Gnomes", 136, Rarity.UNCOMMON, mage.cards.t.TickingGnomes.class)); + cards.add(new SetCardInfo("Tinker", 45, Rarity.UNCOMMON, mage.cards.t.Tinker.class)); + cards.add(new SetCardInfo("Tragic Poet", 24, Rarity.COMMON, mage.cards.t.TragicPoet.class)); + cards.add(new SetCardInfo("Treacherous Link", 71, Rarity.UNCOMMON, mage.cards.t.TreacherousLink.class)); + cards.add(new SetCardInfo("Treefolk Mystic", 114, Rarity.COMMON, mage.cards.t.TreefolkMystic.class)); + cards.add(new SetCardInfo("Treetop Village", 143, Rarity.UNCOMMON, mage.cards.t.TreetopVillage.class)); + cards.add(new SetCardInfo("Unearth", 72, Rarity.COMMON, mage.cards.u.Unearth.class)); + cards.add(new SetCardInfo("Urza's Blueprints", 137, Rarity.RARE, mage.cards.u.UrzasBlueprints.class)); + cards.add(new SetCardInfo("Viashino Bey", 93, Rarity.COMMON, mage.cards.v.ViashinoBey.class)); + cards.add(new SetCardInfo("Viashino Cutthroat", 94, Rarity.UNCOMMON, mage.cards.v.ViashinoCutthroat.class)); + cards.add(new SetCardInfo("Viashino Heretic", 95, Rarity.UNCOMMON, mage.cards.v.ViashinoHeretic.class)); + cards.add(new SetCardInfo("Viashino Sandscout", 96, Rarity.COMMON, mage.cards.v.ViashinoSandscout.class)); + cards.add(new SetCardInfo("Vigilant Drake", 46, Rarity.COMMON, mage.cards.v.VigilantDrake.class)); + cards.add(new SetCardInfo("Walking Sponge", 47, Rarity.UNCOMMON, mage.cards.w.WalkingSponge.class)); + cards.add(new SetCardInfo("Weatherseed Elf", 115, Rarity.COMMON, mage.cards.w.WeatherseedElf.class)); + cards.add(new SetCardInfo("Weatherseed Faeries", 48, Rarity.COMMON, mage.cards.w.WeatherseedFaeries.class)); + cards.add(new SetCardInfo("Weatherseed Treefolk", 116, Rarity.RARE, mage.cards.w.WeatherseedTreefolk.class)); + cards.add(new SetCardInfo("Wheel of Torture", 138, Rarity.RARE, mage.cards.w.WheelOfTorture.class)); + cards.add(new SetCardInfo("Wing Snare", 117, Rarity.UNCOMMON, mage.cards.w.WingSnare.class)); + cards.add(new SetCardInfo("Yavimaya Granger", 118, Rarity.COMMON, mage.cards.y.YavimayaGranger.class)); + cards.add(new SetCardInfo("Yavimaya Scion", 119, Rarity.COMMON, mage.cards.y.YavimayaScion.class)); + cards.add(new SetCardInfo("Yavimaya Wurm", 120, Rarity.COMMON, mage.cards.y.YavimayaWurm.class)); + } +} From c4d13ab37a904de048bf7fba95e0f31725705129 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 16 Nov 2018 11:36:05 -0600 Subject: [PATCH 137/167] - Fixed #5430 --- .../src/mage/cards/e/EtrataTheSilencer.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java b/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java index 9ced408831..fbbef138a6 100644 --- a/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java +++ b/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java @@ -144,14 +144,18 @@ class EtrataTheSilencerEffect extends OneShotEffect { card.addCounters(CounterType.HIT.createInstance(), source, game); } int cardsFound = 0; - for (Card exiledCard : game.getExile().getAllCards(game)) { - if (exiledCard.getCounters(game).getCount(CounterType.HIT) >= 1 && exiledCard.getOwnerId().equals(player.getId())) { - cardsFound++; - } - } + cardsFound = game.getExile().getAllCards(game).stream().filter((exiledCard) -> (exiledCard.getCounters(game).getCount(CounterType.HIT) >= 1 + && exiledCard.getOwnerId().equals(player.getId()))).map((_item) -> 1).reduce(cardsFound, Integer::sum); if (cardsFound > 2) { player.lost(game); } - return new ShuffleIntoLibrarySourceEffect().apply(game, source); + Permanent etrataTheSilencer = game.getPermanent(source.getSourceId()); + if (etrataTheSilencer != null) { + if (etrataTheSilencer.isPhasedIn()) { + return new ShuffleIntoLibrarySourceEffect().apply(game, source); + } + } + controller.shuffleLibrary(source, game); + return true; } } From ed7c32f9e8668d93f90d8a6a0267445fd3312fe2 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 16 Nov 2018 16:14:10 -0600 Subject: [PATCH 138/167] - Added Scrying Glass and Metathrane Elite. --- .../src/mage/cards/m/MetathranElite.java | 47 +++ Mage.Sets/src/mage/cards/s/ScryingGlass.java | 87 +++++ Mage.Sets/src/mage/sets/UrzasDestiny.java | 334 +++++++++--------- 3 files changed, 302 insertions(+), 166 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/m/MetathranElite.java create mode 100644 Mage.Sets/src/mage/cards/s/ScryingGlass.java diff --git a/Mage.Sets/src/mage/cards/m/MetathranElite.java b/Mage.Sets/src/mage/cards/m/MetathranElite.java new file mode 100644 index 0000000000..cfeed06ccf --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MetathranElite.java @@ -0,0 +1,47 @@ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.EnchantedSourceCondition; +import mage.abilities.decorator.ConditionalRestrictionEffect; +import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author jeffwadsworth + */ +public final class MetathranElite extends CardImpl { + + private static final String rule = "{this} is unblockable as long as it's enchanted."; + + public MetathranElite(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); + + this.subtype.add(SubType.METATHRAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Metathran Elite is unblockable as long as it's enchanted. + ConditionalRestrictionEffect effect = new ConditionalRestrictionEffect( + new CantBeBlockedSourceEffect(), new EnchantedSourceCondition()); + effect.setText(rule); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + + } + + public MetathranElite(final MetathranElite card) { + super(card); + } + + @Override + public MetathranElite copy() { + return new MetathranElite(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ScryingGlass.java b/Mage.Sets/src/mage/cards/s/ScryingGlass.java new file mode 100644 index 0000000000..8f53b6f033 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScryingGlass.java @@ -0,0 +1,87 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChoiceColor; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author jeffwadsworth + */ +public final class ScryingGlass extends CardImpl { + + public ScryingGlass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // {3}, {tap}: Choose a number greater than 0 and a color. Target opponent reveals his or her hand. If that opponent reveals exactly the chosen number of cards of the chosen color, you draw a card. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScryingGlassEffect(), new ManaCostsImpl("{3}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + + } + + public ScryingGlass(final ScryingGlass card) { + super(card); + } + + @Override + public ScryingGlass copy() { + return new ScryingGlass(this); + } +} + +class ScryingGlassEffect extends OneShotEffect { + + public ScryingGlassEffect() { + super(Outcome.Neutral); + staticText = "Choose a number greater than 0 and a color. Target opponent reveals his or her hand. If that opponent reveals exactly the chosen number of cards of the chosen color, you draw a card"; + } + + public ScryingGlassEffect(final ScryingGlassEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player targetOpponent = game.getPlayer(source.getFirstTarget()); + ChoiceColor color = new ChoiceColor(); + int amount = 0; + if (controller != null + && targetOpponent != null) { + amount = controller.getAmount(1, Integer.MAX_VALUE, "Choose a number", game); + controller.choose(Outcome.Discard, color, game); + FilterCard filter = new FilterCard(); + filter.add(new ColorPredicate(color.getColor())); + targetOpponent.revealCards(source, targetOpponent.getHand(), game); + if (targetOpponent.getHand().count(filter, game) == amount) { + game.informPlayers(controller.getName() + " has chosen the exact number and color of the revealed cards from " + targetOpponent.getName() + "'s hand. They draw a card."); + controller.drawCards(1, game); + return true; + } else { + game.informPlayers(controller.getName() + " has chosen incorrectly and will not draw a card."); + } + } + return false; + } + + @Override + public ScryingGlassEffect copy() { + return new ScryingGlassEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index 17e0fd38ed..810b12ccff 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -1,166 +1,168 @@ - -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author Backfir3 - */ -public final class UrzasDestiny extends ExpansionSet { - - private static final UrzasDestiny instance = new UrzasDestiny(); - - public static UrzasDestiny getInstance() { - return instance; - } - - private UrzasDestiny() { - super("Urza's Destiny", "UDS", ExpansionSet.buildDate(1999, 6, 7), SetType.EXPANSION); - this.blockName = "Urza"; - this.parentSet = UrzasSaga.getInstance(); - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Academy Rector", 1, Rarity.RARE, mage.cards.a.AcademyRector.class)); - cards.add(new SetCardInfo("Aether Sting", 76, Rarity.UNCOMMON, mage.cards.a.AetherSting.class)); - cards.add(new SetCardInfo("Ancient Silverback", 101, Rarity.RARE, mage.cards.a.AncientSilverback.class)); - cards.add(new SetCardInfo("Apprentice Necromancer", 51, Rarity.RARE, mage.cards.a.ApprenticeNecromancer.class)); - cards.add(new SetCardInfo("Attrition", 52, Rarity.RARE, mage.cards.a.Attrition.class)); - cards.add(new SetCardInfo("Aura Thief", 26, Rarity.RARE, mage.cards.a.AuraThief.class)); - cards.add(new SetCardInfo("Blizzard Elemental", 27, Rarity.RARE, mage.cards.b.BlizzardElemental.class)); - cards.add(new SetCardInfo("Bloodshot Cyclops", 77, Rarity.RARE, mage.cards.b.BloodshotCyclops.class)); - cards.add(new SetCardInfo("Body Snatcher", 53, Rarity.RARE, mage.cards.b.BodySnatcher.class)); - cards.add(new SetCardInfo("Braidwood Cup", 126, Rarity.UNCOMMON, mage.cards.b.BraidwoodCup.class)); - cards.add(new SetCardInfo("Braidwood Sextant", 127, Rarity.UNCOMMON, mage.cards.b.BraidwoodSextant.class)); - cards.add(new SetCardInfo("Brass Secretary", 128, Rarity.UNCOMMON, mage.cards.b.BrassSecretary.class)); - cards.add(new SetCardInfo("Brine Seer", 28, Rarity.UNCOMMON, mage.cards.b.BrineSeer.class)); - cards.add(new SetCardInfo("Bubbling Beebles", 29, Rarity.COMMON, mage.cards.b.BubblingBeebles.class)); - cards.add(new SetCardInfo("Bubbling Muck", 54, Rarity.COMMON, mage.cards.b.BubblingMuck.class)); - cards.add(new SetCardInfo("Caltrops", 129, Rarity.UNCOMMON, mage.cards.c.Caltrops.class)); - cards.add(new SetCardInfo("Capashen Knight", 3, Rarity.COMMON, mage.cards.c.CapashenKnight.class)); - cards.add(new SetCardInfo("Capashen Standard", 4, Rarity.COMMON, mage.cards.c.CapashenStandard.class)); - cards.add(new SetCardInfo("Capashen Templar", 5, Rarity.COMMON, mage.cards.c.CapashenTemplar.class)); - cards.add(new SetCardInfo("Carnival of Souls", 55, Rarity.RARE, mage.cards.c.CarnivalOfSouls.class)); - cards.add(new SetCardInfo("Chime of Night", 56, Rarity.COMMON, mage.cards.c.ChimeOfNight.class)); - cards.add(new SetCardInfo("Cinder Seer", 78, Rarity.UNCOMMON, mage.cards.c.CinderSeer.class)); - cards.add(new SetCardInfo("Colos Yearling", 79, Rarity.COMMON, mage.cards.c.ColosYearling.class)); - cards.add(new SetCardInfo("Compost", 102, Rarity.UNCOMMON, mage.cards.c.Compost.class)); - cards.add(new SetCardInfo("Covetous Dragon", 80, Rarity.RARE, mage.cards.c.CovetousDragon.class)); - cards.add(new SetCardInfo("Disease Carriers", 57, Rarity.COMMON, mage.cards.d.DiseaseCarriers.class)); - cards.add(new SetCardInfo("Donate", 31, Rarity.RARE, mage.cards.d.Donate.class)); - cards.add(new SetCardInfo("Dying Wail", 58, Rarity.COMMON, mage.cards.d.DyingWail.class)); - cards.add(new SetCardInfo("Elvish Lookout", 103, Rarity.COMMON, mage.cards.e.ElvishLookout.class)); - cards.add(new SetCardInfo("Elvish Piper", 104, Rarity.RARE, mage.cards.e.ElvishPiper.class)); - cards.add(new SetCardInfo("Emperor Crocodile", 105, Rarity.RARE, mage.cards.e.EmperorCrocodile.class)); - cards.add(new SetCardInfo("Encroach", 59, Rarity.UNCOMMON, mage.cards.e.Encroach.class)); - cards.add(new SetCardInfo("Eradicate", 60, Rarity.UNCOMMON, mage.cards.e.Eradicate.class)); - cards.add(new SetCardInfo("Extruder", 130, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); - cards.add(new SetCardInfo("False Prophet", 6, Rarity.RARE, mage.cards.f.FalseProphet.class)); - cards.add(new SetCardInfo("Festering Wound", 61, Rarity.UNCOMMON, mage.cards.f.FesteringWound.class)); - cards.add(new SetCardInfo("Field Surgeon", 8, Rarity.COMMON, mage.cards.f.FieldSurgeon.class)); - cards.add(new SetCardInfo("Flame Jet", 81, Rarity.COMMON, mage.cards.f.FlameJet.class)); - cards.add(new SetCardInfo("Fledgling Osprey", 33, Rarity.COMMON, mage.cards.f.FledglingOsprey.class)); - cards.add(new SetCardInfo("Flicker", 9, Rarity.RARE, mage.cards.f.Flicker.class)); - cards.add(new SetCardInfo("Fodder Cannon", 131, Rarity.UNCOMMON, mage.cards.f.FodderCannon.class)); - cards.add(new SetCardInfo("Gamekeeper", 106, Rarity.UNCOMMON, mage.cards.g.Gamekeeper.class)); - cards.add(new SetCardInfo("Goblin Berserker", 82, Rarity.UNCOMMON, mage.cards.g.GoblinBerserker.class)); - cards.add(new SetCardInfo("Goblin Festival", 83, Rarity.RARE, mage.cards.g.GoblinFestival.class)); - cards.add(new SetCardInfo("Goblin Gardener", 84, Rarity.COMMON, mage.cards.g.GoblinGardener.class)); - cards.add(new SetCardInfo("Goblin Marshal", 85, Rarity.RARE, mage.cards.g.GoblinMarshal.class)); - cards.add(new SetCardInfo("Goblin Masons", 86, Rarity.COMMON, mage.cards.g.GoblinMasons.class)); - cards.add(new SetCardInfo("Goliath Beetle", 107, Rarity.COMMON, mage.cards.g.GoliathBeetle.class)); - cards.add(new SetCardInfo("Heart Warden", 108, Rarity.COMMON, mage.cards.h.HeartWarden.class)); - cards.add(new SetCardInfo("Hulking Ogre", 87, Rarity.COMMON, mage.cards.h.HulkingOgre.class)); - cards.add(new SetCardInfo("Hunting Moa", 109, Rarity.UNCOMMON, mage.cards.h.HuntingMoa.class)); - cards.add(new SetCardInfo("Illuminated Wings", 34, Rarity.COMMON, mage.cards.i.IlluminatedWings.class)); - cards.add(new SetCardInfo("Impatience", 88, Rarity.RARE, mage.cards.i.Impatience.class)); - cards.add(new SetCardInfo("Iridescent Drake", 35, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); - cards.add(new SetCardInfo("Ivy Seer", 110, Rarity.UNCOMMON, mage.cards.i.IvySeer.class)); - cards.add(new SetCardInfo("Jasmine Seer", 10, Rarity.UNCOMMON, mage.cards.j.JasmineSeer.class)); - cards.add(new SetCardInfo("Junk Diver", 132, Rarity.RARE, mage.cards.j.JunkDiver.class)); - cards.add(new SetCardInfo("Keldon Champion", 90, Rarity.UNCOMMON, mage.cards.k.KeldonChampion.class)); - cards.add(new SetCardInfo("Keldon Vandals", 91, Rarity.COMMON, mage.cards.k.KeldonVandals.class)); - cards.add(new SetCardInfo("Kingfisher", 36, Rarity.COMMON, mage.cards.k.Kingfisher.class)); - cards.add(new SetCardInfo("Landslide", 92, Rarity.UNCOMMON, mage.cards.l.Landslide.class)); - cards.add(new SetCardInfo("Magnify", 111, Rarity.COMMON, mage.cards.m.Magnify.class)); - cards.add(new SetCardInfo("Mantis Engine", 133, Rarity.UNCOMMON, mage.cards.m.MantisEngine.class)); - cards.add(new SetCardInfo("Marker Beetles", 112, Rarity.COMMON, mage.cards.m.MarkerBeetles.class)); - cards.add(new SetCardInfo("Mark of Fury", 93, Rarity.COMMON, mage.cards.m.MarkOfFury.class)); - cards.add(new SetCardInfo("Mask of Law and Grace", 11, Rarity.COMMON, mage.cards.m.MaskOfLawAndGrace.class)); - cards.add(new SetCardInfo("Master Healer", 12, Rarity.RARE, mage.cards.m.MasterHealer.class)); - cards.add(new SetCardInfo("Masticore", 134, Rarity.RARE, mage.cards.m.Masticore.class)); - cards.add(new SetCardInfo("Mental Discipline", 37, Rarity.COMMON, mage.cards.m.MentalDiscipline.class)); - cards.add(new SetCardInfo("Metalworker", 135, Rarity.RARE, mage.cards.m.Metalworker.class)); - cards.add(new SetCardInfo("Metathran Soldier", 39, Rarity.COMMON, mage.cards.m.MetathranSoldier.class)); - cards.add(new SetCardInfo("Momentum", 113, Rarity.UNCOMMON, mage.cards.m.Momentum.class)); - cards.add(new SetCardInfo("Multani's Decree", 114, Rarity.COMMON, mage.cards.m.MultanisDecree.class)); - cards.add(new SetCardInfo("Nightshade Seer", 63, Rarity.UNCOMMON, mage.cards.n.NightshadeSeer.class)); - cards.add(new SetCardInfo("Opalescence", 13, Rarity.RARE, mage.cards.o.Opalescence.class)); - cards.add(new SetCardInfo("Opposition", 40, Rarity.RARE, mage.cards.o.Opposition.class)); - cards.add(new SetCardInfo("Pattern of Rebirth", 115, Rarity.RARE, mage.cards.p.PatternOfRebirth.class)); - cards.add(new SetCardInfo("Phyrexian Monitor", 64, Rarity.COMMON, mage.cards.p.PhyrexianMonitor.class)); - cards.add(new SetCardInfo("Phyrexian Negator", 65, Rarity.RARE, mage.cards.p.PhyrexianNegator.class)); - cards.add(new SetCardInfo("Plague Dogs", 66, Rarity.UNCOMMON, mage.cards.p.PlagueDogs.class)); - cards.add(new SetCardInfo("Plated Spider", 116, Rarity.COMMON, mage.cards.p.PlatedSpider.class)); - cards.add(new SetCardInfo("Plow Under", 117, Rarity.RARE, mage.cards.p.PlowUnder.class)); - cards.add(new SetCardInfo("Powder Keg", 136, Rarity.RARE, mage.cards.p.PowderKeg.class)); - cards.add(new SetCardInfo("Quash", 42, Rarity.UNCOMMON, mage.cards.q.Quash.class)); - cards.add(new SetCardInfo("Rapid Decay", 67, Rarity.RARE, mage.cards.r.RapidDecay.class)); - cards.add(new SetCardInfo("Ravenous Rats", 68, Rarity.COMMON, mage.cards.r.RavenousRats.class)); - cards.add(new SetCardInfo("Rayne, Academy Chancellor", 43, Rarity.RARE, mage.cards.r.RayneAcademyChancellor.class)); - cards.add(new SetCardInfo("Reckless Abandon", 94, Rarity.COMMON, mage.cards.r.RecklessAbandon.class)); - cards.add(new SetCardInfo("Reliquary Monk", 14, Rarity.COMMON, mage.cards.r.ReliquaryMonk.class)); - cards.add(new SetCardInfo("Repercussion", 95, Rarity.RARE, mage.cards.r.Repercussion.class)); - cards.add(new SetCardInfo("Replenish", 15, Rarity.RARE, mage.cards.r.Replenish.class)); - cards.add(new SetCardInfo("Rescue", 44, Rarity.COMMON, mage.cards.r.Rescue.class)); - cards.add(new SetCardInfo("Rofellos's Gift", 119, Rarity.COMMON, mage.cards.r.RofellossGift.class)); - cards.add(new SetCardInfo("Rofellos, Llanowar Emissary", 118, Rarity.RARE, mage.cards.r.RofellosLlanowarEmissary.class)); - cards.add(new SetCardInfo("Sanctimony", 16, Rarity.UNCOMMON, mage.cards.s.Sanctimony.class)); - cards.add(new SetCardInfo("Scent of Brine", 45, Rarity.COMMON, mage.cards.s.ScentOfBrine.class)); - cards.add(new SetCardInfo("Scent of Cinder", 96, Rarity.COMMON, mage.cards.s.ScentOfCinder.class)); - cards.add(new SetCardInfo("Scent of Ivy", 120, Rarity.COMMON, mage.cards.s.ScentOfIvy.class)); - cards.add(new SetCardInfo("Scent of Jasmine", 17, Rarity.COMMON, mage.cards.s.ScentOfJasmine.class)); - cards.add(new SetCardInfo("Scent of Nightshade", 69, Rarity.COMMON, mage.cards.s.ScentOfNightshade.class)); - cards.add(new SetCardInfo("Scour", 18, Rarity.UNCOMMON, mage.cards.s.Scour.class)); - cards.add(new SetCardInfo("Serra Advocate", 19, Rarity.UNCOMMON, mage.cards.s.SerraAdvocate.class)); - cards.add(new SetCardInfo("Sigil of Sleep", 46, Rarity.COMMON, mage.cards.s.SigilOfSleep.class)); - cards.add(new SetCardInfo("Skittering Horror", 70, Rarity.COMMON, mage.cards.s.SkitteringHorror.class)); - cards.add(new SetCardInfo("Slinking Skirge", 71, Rarity.COMMON, mage.cards.s.SlinkingSkirge.class)); - cards.add(new SetCardInfo("Solidarity", 20, Rarity.COMMON, mage.cards.s.Solidarity.class)); - cards.add(new SetCardInfo("Soul Feast", 72, Rarity.UNCOMMON, mage.cards.s.SoulFeast.class)); - cards.add(new SetCardInfo("Sowing Salt", 97, Rarity.UNCOMMON, mage.cards.s.SowingSalt.class)); - cards.add(new SetCardInfo("Splinter", 121, Rarity.UNCOMMON, mage.cards.s.Splinter.class)); - cards.add(new SetCardInfo("Squirming Mass", 73, Rarity.COMMON, mage.cards.s.SquirmingMass.class)); - cards.add(new SetCardInfo("Storage Matrix", 138, Rarity.RARE, mage.cards.s.StorageMatrix.class)); - cards.add(new SetCardInfo("Taunting Elf", 122, Rarity.COMMON, mage.cards.t.TauntingElf.class)); - cards.add(new SetCardInfo("Telepathic Spies", 47, Rarity.COMMON, mage.cards.t.TelepathicSpies.class)); - cards.add(new SetCardInfo("Temporal Adept", 48, Rarity.RARE, mage.cards.t.TemporalAdept.class)); - cards.add(new SetCardInfo("Tethered Griffin", 21, Rarity.RARE, mage.cards.t.TetheredGriffin.class)); - cards.add(new SetCardInfo("Thieving Magpie", 49, Rarity.UNCOMMON, mage.cards.t.ThievingMagpie.class)); - cards.add(new SetCardInfo("Thorn Elemental", 123, Rarity.RARE, mage.cards.t.ThornElemental.class)); - cards.add(new SetCardInfo("Thran Dynamo", 139, Rarity.UNCOMMON, mage.cards.t.ThranDynamo.class)); - cards.add(new SetCardInfo("Thran Foundry", 140, Rarity.UNCOMMON, mage.cards.t.ThranFoundry.class)); - cards.add(new SetCardInfo("Thran Golem", 141, Rarity.RARE, mage.cards.t.ThranGolem.class)); - cards.add(new SetCardInfo("Tormented Angel", 22, Rarity.COMMON, mage.cards.t.TormentedAngel.class)); - cards.add(new SetCardInfo("Treachery", 50, Rarity.RARE, mage.cards.t.Treachery.class)); - cards.add(new SetCardInfo("Trumpet Blast", 98, Rarity.COMMON, mage.cards.t.TrumpetBlast.class)); - cards.add(new SetCardInfo("Twisted Experiment", 74, Rarity.COMMON, mage.cards.t.TwistedExperiment.class)); - cards.add(new SetCardInfo("Urza's Incubator", 142, Rarity.RARE, mage.cards.u.UrzasIncubator.class)); - cards.add(new SetCardInfo("Voice of Duty", 23, Rarity.UNCOMMON, mage.cards.v.VoiceOfDuty.class)); - cards.add(new SetCardInfo("Voice of Reason", 24, Rarity.UNCOMMON, mage.cards.v.VoiceOfReason.class)); - cards.add(new SetCardInfo("Wake of Destruction", 99, Rarity.RARE, mage.cards.w.WakeOfDestruction.class)); - cards.add(new SetCardInfo("Wall of Glare", 25, Rarity.COMMON, mage.cards.w.WallOfGlare.class)); - cards.add(new SetCardInfo("Wild Colos", 100, Rarity.COMMON, mage.cards.w.WildColos.class)); - cards.add(new SetCardInfo("Yavimaya Elder", 124, Rarity.COMMON, mage.cards.y.YavimayaElder.class)); - cards.add(new SetCardInfo("Yavimaya Enchantress", 125, Rarity.UNCOMMON, mage.cards.y.YavimayaEnchantress.class)); - cards.add(new SetCardInfo("Yavimaya Hollow", 143, Rarity.RARE, mage.cards.y.YavimayaHollow.class)); - cards.add(new SetCardInfo("Yawgmoth's Bargain", 75, Rarity.RARE, mage.cards.y.YawgmothsBargain.class)); - } -} + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author Backfir3 + */ +public final class UrzasDestiny extends ExpansionSet { + + private static final UrzasDestiny instance = new UrzasDestiny(); + + public static UrzasDestiny getInstance() { + return instance; + } + + private UrzasDestiny() { + super("Urza's Destiny", "UDS", ExpansionSet.buildDate(1999, 6, 7), SetType.EXPANSION); + this.blockName = "Urza"; + this.parentSet = UrzasSaga.getInstance(); + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Academy Rector", 1, Rarity.RARE, mage.cards.a.AcademyRector.class)); + cards.add(new SetCardInfo("Aether Sting", 76, Rarity.UNCOMMON, mage.cards.a.AetherSting.class)); + cards.add(new SetCardInfo("Ancient Silverback", 101, Rarity.RARE, mage.cards.a.AncientSilverback.class)); + cards.add(new SetCardInfo("Apprentice Necromancer", 51, Rarity.RARE, mage.cards.a.ApprenticeNecromancer.class)); + cards.add(new SetCardInfo("Attrition", 52, Rarity.RARE, mage.cards.a.Attrition.class)); + cards.add(new SetCardInfo("Aura Thief", 26, Rarity.RARE, mage.cards.a.AuraThief.class)); + cards.add(new SetCardInfo("Blizzard Elemental", 27, Rarity.RARE, mage.cards.b.BlizzardElemental.class)); + cards.add(new SetCardInfo("Bloodshot Cyclops", 77, Rarity.RARE, mage.cards.b.BloodshotCyclops.class)); + cards.add(new SetCardInfo("Body Snatcher", 53, Rarity.RARE, mage.cards.b.BodySnatcher.class)); + cards.add(new SetCardInfo("Braidwood Cup", 126, Rarity.UNCOMMON, mage.cards.b.BraidwoodCup.class)); + cards.add(new SetCardInfo("Braidwood Sextant", 127, Rarity.UNCOMMON, mage.cards.b.BraidwoodSextant.class)); + cards.add(new SetCardInfo("Brass Secretary", 128, Rarity.UNCOMMON, mage.cards.b.BrassSecretary.class)); + cards.add(new SetCardInfo("Brine Seer", 28, Rarity.UNCOMMON, mage.cards.b.BrineSeer.class)); + cards.add(new SetCardInfo("Bubbling Beebles", 29, Rarity.COMMON, mage.cards.b.BubblingBeebles.class)); + cards.add(new SetCardInfo("Bubbling Muck", 54, Rarity.COMMON, mage.cards.b.BubblingMuck.class)); + cards.add(new SetCardInfo("Caltrops", 129, Rarity.UNCOMMON, mage.cards.c.Caltrops.class)); + cards.add(new SetCardInfo("Capashen Knight", 3, Rarity.COMMON, mage.cards.c.CapashenKnight.class)); + cards.add(new SetCardInfo("Capashen Standard", 4, Rarity.COMMON, mage.cards.c.CapashenStandard.class)); + cards.add(new SetCardInfo("Capashen Templar", 5, Rarity.COMMON, mage.cards.c.CapashenTemplar.class)); + cards.add(new SetCardInfo("Carnival of Souls", 55, Rarity.RARE, mage.cards.c.CarnivalOfSouls.class)); + cards.add(new SetCardInfo("Chime of Night", 56, Rarity.COMMON, mage.cards.c.ChimeOfNight.class)); + cards.add(new SetCardInfo("Cinder Seer", 78, Rarity.UNCOMMON, mage.cards.c.CinderSeer.class)); + cards.add(new SetCardInfo("Colos Yearling", 79, Rarity.COMMON, mage.cards.c.ColosYearling.class)); + cards.add(new SetCardInfo("Compost", 102, Rarity.UNCOMMON, mage.cards.c.Compost.class)); + cards.add(new SetCardInfo("Covetous Dragon", 80, Rarity.RARE, mage.cards.c.CovetousDragon.class)); + cards.add(new SetCardInfo("Disease Carriers", 57, Rarity.COMMON, mage.cards.d.DiseaseCarriers.class)); + cards.add(new SetCardInfo("Donate", 31, Rarity.RARE, mage.cards.d.Donate.class)); + cards.add(new SetCardInfo("Dying Wail", 58, Rarity.COMMON, mage.cards.d.DyingWail.class)); + cards.add(new SetCardInfo("Elvish Lookout", 103, Rarity.COMMON, mage.cards.e.ElvishLookout.class)); + cards.add(new SetCardInfo("Elvish Piper", 104, Rarity.RARE, mage.cards.e.ElvishPiper.class)); + cards.add(new SetCardInfo("Emperor Crocodile", 105, Rarity.RARE, mage.cards.e.EmperorCrocodile.class)); + cards.add(new SetCardInfo("Encroach", 59, Rarity.UNCOMMON, mage.cards.e.Encroach.class)); + cards.add(new SetCardInfo("Eradicate", 60, Rarity.UNCOMMON, mage.cards.e.Eradicate.class)); + cards.add(new SetCardInfo("Extruder", 130, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); + cards.add(new SetCardInfo("False Prophet", 6, Rarity.RARE, mage.cards.f.FalseProphet.class)); + cards.add(new SetCardInfo("Festering Wound", 61, Rarity.UNCOMMON, mage.cards.f.FesteringWound.class)); + cards.add(new SetCardInfo("Field Surgeon", 8, Rarity.COMMON, mage.cards.f.FieldSurgeon.class)); + cards.add(new SetCardInfo("Flame Jet", 81, Rarity.COMMON, mage.cards.f.FlameJet.class)); + cards.add(new SetCardInfo("Fledgling Osprey", 33, Rarity.COMMON, mage.cards.f.FledglingOsprey.class)); + cards.add(new SetCardInfo("Flicker", 9, Rarity.RARE, mage.cards.f.Flicker.class)); + cards.add(new SetCardInfo("Fodder Cannon", 131, Rarity.UNCOMMON, mage.cards.f.FodderCannon.class)); + cards.add(new SetCardInfo("Gamekeeper", 106, Rarity.UNCOMMON, mage.cards.g.Gamekeeper.class)); + cards.add(new SetCardInfo("Goblin Berserker", 82, Rarity.UNCOMMON, mage.cards.g.GoblinBerserker.class)); + cards.add(new SetCardInfo("Goblin Festival", 83, Rarity.RARE, mage.cards.g.GoblinFestival.class)); + cards.add(new SetCardInfo("Goblin Gardener", 84, Rarity.COMMON, mage.cards.g.GoblinGardener.class)); + cards.add(new SetCardInfo("Goblin Marshal", 85, Rarity.RARE, mage.cards.g.GoblinMarshal.class)); + cards.add(new SetCardInfo("Goblin Masons", 86, Rarity.COMMON, mage.cards.g.GoblinMasons.class)); + cards.add(new SetCardInfo("Goliath Beetle", 107, Rarity.COMMON, mage.cards.g.GoliathBeetle.class)); + cards.add(new SetCardInfo("Heart Warden", 108, Rarity.COMMON, mage.cards.h.HeartWarden.class)); + cards.add(new SetCardInfo("Hulking Ogre", 87, Rarity.COMMON, mage.cards.h.HulkingOgre.class)); + cards.add(new SetCardInfo("Hunting Moa", 109, Rarity.UNCOMMON, mage.cards.h.HuntingMoa.class)); + cards.add(new SetCardInfo("Illuminated Wings", 34, Rarity.COMMON, mage.cards.i.IlluminatedWings.class)); + cards.add(new SetCardInfo("Impatience", 88, Rarity.RARE, mage.cards.i.Impatience.class)); + cards.add(new SetCardInfo("Iridescent Drake", 35, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); + cards.add(new SetCardInfo("Ivy Seer", 110, Rarity.UNCOMMON, mage.cards.i.IvySeer.class)); + cards.add(new SetCardInfo("Jasmine Seer", 10, Rarity.UNCOMMON, mage.cards.j.JasmineSeer.class)); + cards.add(new SetCardInfo("Junk Diver", 132, Rarity.RARE, mage.cards.j.JunkDiver.class)); + cards.add(new SetCardInfo("Keldon Champion", 90, Rarity.UNCOMMON, mage.cards.k.KeldonChampion.class)); + cards.add(new SetCardInfo("Keldon Vandals", 91, Rarity.COMMON, mage.cards.k.KeldonVandals.class)); + cards.add(new SetCardInfo("Kingfisher", 36, Rarity.COMMON, mage.cards.k.Kingfisher.class)); + cards.add(new SetCardInfo("Landslide", 92, Rarity.UNCOMMON, mage.cards.l.Landslide.class)); + cards.add(new SetCardInfo("Magnify", 111, Rarity.COMMON, mage.cards.m.Magnify.class)); + cards.add(new SetCardInfo("Mantis Engine", 133, Rarity.UNCOMMON, mage.cards.m.MantisEngine.class)); + cards.add(new SetCardInfo("Marker Beetles", 112, Rarity.COMMON, mage.cards.m.MarkerBeetles.class)); + cards.add(new SetCardInfo("Mark of Fury", 93, Rarity.COMMON, mage.cards.m.MarkOfFury.class)); + cards.add(new SetCardInfo("Mask of Law and Grace", 11, Rarity.COMMON, mage.cards.m.MaskOfLawAndGrace.class)); + cards.add(new SetCardInfo("Master Healer", 12, Rarity.RARE, mage.cards.m.MasterHealer.class)); + cards.add(new SetCardInfo("Masticore", 134, Rarity.RARE, mage.cards.m.Masticore.class)); + cards.add(new SetCardInfo("Mental Discipline", 37, Rarity.COMMON, mage.cards.m.MentalDiscipline.class)); + cards.add(new SetCardInfo("Metalworker", 135, Rarity.RARE, mage.cards.m.Metalworker.class)); + cards.add(new SetCardInfo("Metathran Elite", 38, Rarity.UNCOMMON, mage.cards.m.MetathranElite.class)); + cards.add(new SetCardInfo("Metathran Soldier", 39, Rarity.COMMON, mage.cards.m.MetathranSoldier.class)); + cards.add(new SetCardInfo("Momentum", 113, Rarity.UNCOMMON, mage.cards.m.Momentum.class)); + cards.add(new SetCardInfo("Multani's Decree", 114, Rarity.COMMON, mage.cards.m.MultanisDecree.class)); + cards.add(new SetCardInfo("Nightshade Seer", 63, Rarity.UNCOMMON, mage.cards.n.NightshadeSeer.class)); + cards.add(new SetCardInfo("Opalescence", 13, Rarity.RARE, mage.cards.o.Opalescence.class)); + cards.add(new SetCardInfo("Opposition", 40, Rarity.RARE, mage.cards.o.Opposition.class)); + cards.add(new SetCardInfo("Pattern of Rebirth", 115, Rarity.RARE, mage.cards.p.PatternOfRebirth.class)); + cards.add(new SetCardInfo("Phyrexian Monitor", 64, Rarity.COMMON, mage.cards.p.PhyrexianMonitor.class)); + cards.add(new SetCardInfo("Phyrexian Negator", 65, Rarity.RARE, mage.cards.p.PhyrexianNegator.class)); + cards.add(new SetCardInfo("Plague Dogs", 66, Rarity.UNCOMMON, mage.cards.p.PlagueDogs.class)); + cards.add(new SetCardInfo("Plated Spider", 116, Rarity.COMMON, mage.cards.p.PlatedSpider.class)); + cards.add(new SetCardInfo("Plow Under", 117, Rarity.RARE, mage.cards.p.PlowUnder.class)); + cards.add(new SetCardInfo("Powder Keg", 136, Rarity.RARE, mage.cards.p.PowderKeg.class)); + cards.add(new SetCardInfo("Quash", 42, Rarity.UNCOMMON, mage.cards.q.Quash.class)); + cards.add(new SetCardInfo("Rapid Decay", 67, Rarity.RARE, mage.cards.r.RapidDecay.class)); + cards.add(new SetCardInfo("Ravenous Rats", 68, Rarity.COMMON, mage.cards.r.RavenousRats.class)); + cards.add(new SetCardInfo("Rayne, Academy Chancellor", 43, Rarity.RARE, mage.cards.r.RayneAcademyChancellor.class)); + cards.add(new SetCardInfo("Reckless Abandon", 94, Rarity.COMMON, mage.cards.r.RecklessAbandon.class)); + cards.add(new SetCardInfo("Reliquary Monk", 14, Rarity.COMMON, mage.cards.r.ReliquaryMonk.class)); + cards.add(new SetCardInfo("Repercussion", 95, Rarity.RARE, mage.cards.r.Repercussion.class)); + cards.add(new SetCardInfo("Replenish", 15, Rarity.RARE, mage.cards.r.Replenish.class)); + cards.add(new SetCardInfo("Rescue", 44, Rarity.COMMON, mage.cards.r.Rescue.class)); + cards.add(new SetCardInfo("Rofellos's Gift", 119, Rarity.COMMON, mage.cards.r.RofellossGift.class)); + cards.add(new SetCardInfo("Rofellos, Llanowar Emissary", 118, Rarity.RARE, mage.cards.r.RofellosLlanowarEmissary.class)); + cards.add(new SetCardInfo("Sanctimony", 16, Rarity.UNCOMMON, mage.cards.s.Sanctimony.class)); + cards.add(new SetCardInfo("Scent of Brine", 45, Rarity.COMMON, mage.cards.s.ScentOfBrine.class)); + cards.add(new SetCardInfo("Scent of Cinder", 96, Rarity.COMMON, mage.cards.s.ScentOfCinder.class)); + cards.add(new SetCardInfo("Scent of Ivy", 120, Rarity.COMMON, mage.cards.s.ScentOfIvy.class)); + cards.add(new SetCardInfo("Scent of Jasmine", 17, Rarity.COMMON, mage.cards.s.ScentOfJasmine.class)); + cards.add(new SetCardInfo("Scent of Nightshade", 69, Rarity.COMMON, mage.cards.s.ScentOfNightshade.class)); + cards.add(new SetCardInfo("Scour", 18, Rarity.UNCOMMON, mage.cards.s.Scour.class)); + cards.add(new SetCardInfo("Scrying Glass", 137, Rarity.RARE, mage.cards.s.ScryingGlass.class)); + cards.add(new SetCardInfo("Serra Advocate", 19, Rarity.UNCOMMON, mage.cards.s.SerraAdvocate.class)); + cards.add(new SetCardInfo("Sigil of Sleep", 46, Rarity.COMMON, mage.cards.s.SigilOfSleep.class)); + cards.add(new SetCardInfo("Skittering Horror", 70, Rarity.COMMON, mage.cards.s.SkitteringHorror.class)); + cards.add(new SetCardInfo("Slinking Skirge", 71, Rarity.COMMON, mage.cards.s.SlinkingSkirge.class)); + cards.add(new SetCardInfo("Solidarity", 20, Rarity.COMMON, mage.cards.s.Solidarity.class)); + cards.add(new SetCardInfo("Soul Feast", 72, Rarity.UNCOMMON, mage.cards.s.SoulFeast.class)); + cards.add(new SetCardInfo("Sowing Salt", 97, Rarity.UNCOMMON, mage.cards.s.SowingSalt.class)); + cards.add(new SetCardInfo("Splinter", 121, Rarity.UNCOMMON, mage.cards.s.Splinter.class)); + cards.add(new SetCardInfo("Squirming Mass", 73, Rarity.COMMON, mage.cards.s.SquirmingMass.class)); + cards.add(new SetCardInfo("Storage Matrix", 138, Rarity.RARE, mage.cards.s.StorageMatrix.class)); + cards.add(new SetCardInfo("Taunting Elf", 122, Rarity.COMMON, mage.cards.t.TauntingElf.class)); + cards.add(new SetCardInfo("Telepathic Spies", 47, Rarity.COMMON, mage.cards.t.TelepathicSpies.class)); + cards.add(new SetCardInfo("Temporal Adept", 48, Rarity.RARE, mage.cards.t.TemporalAdept.class)); + cards.add(new SetCardInfo("Tethered Griffin", 21, Rarity.RARE, mage.cards.t.TetheredGriffin.class)); + cards.add(new SetCardInfo("Thieving Magpie", 49, Rarity.UNCOMMON, mage.cards.t.ThievingMagpie.class)); + cards.add(new SetCardInfo("Thorn Elemental", 123, Rarity.RARE, mage.cards.t.ThornElemental.class)); + cards.add(new SetCardInfo("Thran Dynamo", 139, Rarity.UNCOMMON, mage.cards.t.ThranDynamo.class)); + cards.add(new SetCardInfo("Thran Foundry", 140, Rarity.UNCOMMON, mage.cards.t.ThranFoundry.class)); + cards.add(new SetCardInfo("Thran Golem", 141, Rarity.RARE, mage.cards.t.ThranGolem.class)); + cards.add(new SetCardInfo("Tormented Angel", 22, Rarity.COMMON, mage.cards.t.TormentedAngel.class)); + cards.add(new SetCardInfo("Treachery", 50, Rarity.RARE, mage.cards.t.Treachery.class)); + cards.add(new SetCardInfo("Trumpet Blast", 98, Rarity.COMMON, mage.cards.t.TrumpetBlast.class)); + cards.add(new SetCardInfo("Twisted Experiment", 74, Rarity.COMMON, mage.cards.t.TwistedExperiment.class)); + cards.add(new SetCardInfo("Urza's Incubator", 142, Rarity.RARE, mage.cards.u.UrzasIncubator.class)); + cards.add(new SetCardInfo("Voice of Duty", 23, Rarity.UNCOMMON, mage.cards.v.VoiceOfDuty.class)); + cards.add(new SetCardInfo("Voice of Reason", 24, Rarity.UNCOMMON, mage.cards.v.VoiceOfReason.class)); + cards.add(new SetCardInfo("Wake of Destruction", 99, Rarity.RARE, mage.cards.w.WakeOfDestruction.class)); + cards.add(new SetCardInfo("Wall of Glare", 25, Rarity.COMMON, mage.cards.w.WallOfGlare.class)); + cards.add(new SetCardInfo("Wild Colos", 100, Rarity.COMMON, mage.cards.w.WildColos.class)); + cards.add(new SetCardInfo("Yavimaya Elder", 124, Rarity.COMMON, mage.cards.y.YavimayaElder.class)); + cards.add(new SetCardInfo("Yavimaya Enchantress", 125, Rarity.UNCOMMON, mage.cards.y.YavimayaEnchantress.class)); + cards.add(new SetCardInfo("Yavimaya Hollow", 143, Rarity.RARE, mage.cards.y.YavimayaHollow.class)); + cards.add(new SetCardInfo("Yawgmoth's Bargain", 75, Rarity.RARE, mage.cards.y.YawgmothsBargain.class)); + } +} From 92d1b5c51af676a089d44b1d11d9cd1e6d4449d8 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 17 Nov 2018 02:48:50 +0400 Subject: [PATCH 139/167] * UI: added new skill level column with star icons instead text; --- .../java/mage/client/table/TablesPanel.java | 3493 +++++++++-------- .../mage/card/arcane/CardRendererUtils.java | 35 +- .../card/arcane/ManaSymbolsCellRenderer.java | 39 +- .../main/resources/info/yellow_star_16.png | Bin 0 -> 478 bytes .../main/resources/info/yellow_star_24.png | Bin 0 -> 658 bytes .../main/resources/info/yellow_star_32.png | Bin 0 -> 931 bytes 6 files changed, 1817 insertions(+), 1750 deletions(-) create mode 100644 Mage.Client/src/main/resources/info/yellow_star_16.png create mode 100644 Mage.Client/src/main/resources/info/yellow_star_24.png create mode 100644 Mage.Client/src/main/resources/info/yellow_star_32.png diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 59c4d88805..30c5d8e4ac 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -1,163 +1,193 @@ - - /* - * TablesPanel.java - * - * Created on 15-Dec-2009, 10:54:01 PM - */ -package mage.client.table; + * TablesPanel.java + * + * Created on 15-Dec-2009, 10:54:01 PM + */ + package mage.client.table; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.beans.PropertyVetoException; -import java.io.File; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import javax.swing.*; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.TableCellRenderer; -import mage.cards.decks.importer.DeckImporterUtil; -import mage.client.MageFrame; -import mage.client.SessionHandler; -import mage.client.chat.ChatPanelBasic; -import mage.client.components.MageComponents; -import mage.client.dialog.*; -import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_ORDER; -import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH; -import static mage.client.dialog.PreferencesDialog.KEY_TABLES_FILTER_SETTINGS; -import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1; -import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2; -import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3; -import mage.client.util.ButtonColumn; -import mage.client.util.GUISizeHelper; -import mage.client.util.IgnoreList; -import mage.client.util.MageTableRowSorter; -import mage.client.util.URLHandler; -import mage.client.util.gui.GuiDisplayUtil; -import mage.client.util.gui.TableUtil; -import mage.constants.*; -import mage.game.match.MatchOptions; -import mage.players.PlayerType; -import mage.remote.MageRemoteException; -import mage.view.MatchView; -import mage.view.RoomUsersView; -import mage.view.TableView; -import mage.view.UserRequestMessage; -import org.apache.log4j.Logger; -import org.ocpsoft.prettytime.Duration; -import org.ocpsoft.prettytime.PrettyTime; -import org.ocpsoft.prettytime.units.JustNow; + import mage.cards.decks.importer.DeckImporterUtil; + import mage.client.MageFrame; + import mage.client.SessionHandler; + import mage.client.chat.ChatPanelBasic; + import mage.client.components.MageComponents; + import mage.client.dialog.*; + import mage.client.util.*; + import mage.client.util.gui.GuiDisplayUtil; + import mage.client.util.gui.TableUtil; + import mage.constants.*; + import mage.game.match.MatchOptions; + import mage.players.PlayerType; + import mage.remote.MageRemoteException; + import mage.view.MatchView; + import mage.view.RoomUsersView; + import mage.view.TableView; + import mage.view.UserRequestMessage; + import org.apache.log4j.Logger; + import org.mage.card.arcane.CardRendererUtils; + import org.ocpsoft.prettytime.Duration; + import org.ocpsoft.prettytime.PrettyTime; + import org.ocpsoft.prettytime.units.JustNow; -/** - * - * @author BetaSteward_at_googlemail.com - */ -public class TablesPanel extends javax.swing.JPanel { + import javax.swing.*; + import javax.swing.border.EmptyBorder; + import javax.swing.table.AbstractTableModel; + import javax.swing.table.DefaultTableCellRenderer; + import javax.swing.table.TableCellRenderer; + import java.awt.*; + import java.awt.event.ActionEvent; + import java.awt.event.MouseAdapter; + import java.awt.event.MouseEvent; + import java.beans.PropertyVetoException; + import java.io.File; + import java.text.DateFormat; + import java.text.SimpleDateFormat; + import java.util.*; + import java.util.concurrent.CancellationException; + import java.util.concurrent.ExecutionException; + import java.util.concurrent.Executors; + import java.util.concurrent.TimeUnit; - private static final Logger LOGGER = Logger.getLogger(TablesPanel.class); - private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 40, 60}; + import static mage.client.dialog.PreferencesDialog.*; - private final TableTableModel tableModel; - private final MatchesTableModel matchesModel; - private UUID roomId; - private UpdateTablesTask updateTablesTask; - private UpdatePlayersTask updatePlayersTask; - private UpdateMatchesTask updateMatchesTask; - private JoinTableDialog joinTableDialog; - private NewTableDialog newTableDialog; - private NewTournamentDialog newTournamentDialog; - private final GameChooser gameChooser; - private java.util.List messages; - private int currentMessage; - private final MageTableRowSorter activeTablesSorter; - private final MageTableRowSorter completedTablesSorter; + /** + * @author BetaSteward_at_googlemail.com + */ + public class TablesPanel extends javax.swing.JPanel { - private final ButtonColumn actionButton1; - private final ButtonColumn actionButton2; + private static final Logger LOGGER = Logger.getLogger(TablesPanel.class); + private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 40, 60}; - final JToggleButton[] filterButtons; + private final TableTableModel tableModel; + private final MatchesTableModel matchesModel; + private UUID roomId; + private UpdateTablesTask updateTablesTask; + private UpdatePlayersTask updatePlayersTask; + private UpdateMatchesTask updateMatchesTask; + private JoinTableDialog joinTableDialog; + private NewTableDialog newTableDialog; + private NewTournamentDialog newTournamentDialog; + private final GameChooser gameChooser; + private java.util.List messages; + private int currentMessage; + private final MageTableRowSorter activeTablesSorter; + private final MageTableRowSorter completedTablesSorter; - // time formater - private PrettyTime timeFormater = new PrettyTime(); + private final ButtonColumn actionButton1; + private final ButtonColumn actionButton2; - // time ago renderer - TableCellRenderer timeAgoCellRenderer = new DefaultTableCellRenderer() { - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - Date d = (Date) value; - label.setText(timeFormater.format(d)); - return label; - } - }; + final JToggleButton[] filterButtons; - // duration renderer - TableCellRenderer durationCellRenderer = new DefaultTableCellRenderer() { - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - Long ms = (Long) value; + // time formater + private PrettyTime timeFormater = new PrettyTime(); - if (ms != 0) { - Duration dur = timeFormater.approximateDuration(new Date(ms)); - label.setText((timeFormater.formatDuration(dur))); - } else { - label.setText(""); - } - return label; - } - }; + // time ago renderer + TableCellRenderer timeAgoCellRenderer = new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + Date d = (Date) value; + label.setText(timeFormater.format(d)); + return label; + } + }; - // datetime render - TableCellRenderer datetimeCellRenderer = new DefaultTableCellRenderer() { - DateFormat datetimeFormater = new SimpleDateFormat("HH:mm:ss"); + // duration renderer + TableCellRenderer durationCellRenderer = new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + Long ms = (Long) value; - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - Date d = (Date) value; - if (d != null) { - label.setText(datetimeFormater.format(d)); - } else { - label.setText(""); - } + if (ms != 0) { + Duration dur = timeFormater.approximateDuration(new Date(ms)); + label.setText((timeFormater.formatDuration(dur))); + } else { + label.setText(""); + } + return label; + } + }; - return label; - } - }; + // datetime render + TableCellRenderer datetimeCellRenderer = new DefaultTableCellRenderer() { + DateFormat datetimeFormater = new SimpleDateFormat("HH:mm:ss"); - /** - * Creates new form TablesPanel - */ - public TablesPanel() { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + Date d = (Date) value; + if (d != null) { + label.setText(datetimeFormater.format(d)); + } else { + label.setText(""); + } - tableModel = new TableTableModel(); - matchesModel = new MatchesTableModel(); - gameChooser = new GameChooser(); + return label; + } + }; - initComponents(); - // tableModel.setSession(session); + // skill renderer + TableCellRenderer skillCellRenderer = new DefaultTableCellRenderer() { - // formater - timeFormater.setLocale(Locale.ENGLISH); - JustNow jn = timeFormater.getUnit(JustNow.class); - jn.setMaxQuantity(1000L * 30L); // 30 seconds gap (show "just now" from 0 to 30 secs) + // base panel to render + private JPanel renderPanel = new JPanel(); + private ImageIcon skillIcon = new ImageIcon(this.getClass().getResource("/info/yellow_star_16.png")); - // 1. TABLE CURRENT - tableTables.createDefaultColumnsFromModel(); - activeTablesSorter = new MageTableRowSorter(tableModel); - tableTables.setRowSorter(activeTablesSorter); + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + + // get table text cell settings + DefaultTableCellRenderer baseRenderer = (DefaultTableCellRenderer) table.getDefaultRenderer(String.class); + JLabel baseComp = (JLabel) baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + String skillCode = baseComp.getText(); + + // apply settings to render panel from parent + renderPanel.setOpaque(baseComp.isOpaque()); + renderPanel.setForeground(CardRendererUtils.copyColor(baseComp.getForeground())); + renderPanel.setBackground(CardRendererUtils.copyColor(baseComp.getBackground())); + renderPanel.setBorder(baseComp.getBorder()); + + // create each skill symbol as child label + renderPanel.removeAll(); + renderPanel.setLayout(new BoxLayout(renderPanel, BoxLayout.X_AXIS)); + for (char skillSymbol : skillCode.toCharArray()) { + JLabel symbolLabel = new JLabel(); + symbolLabel.setBorder(new EmptyBorder(0, 3, 0, 0)); + symbolLabel.setIcon(skillIcon); + renderPanel.add(symbolLabel); + } + + return renderPanel; + } + }; + + /** + * Creates new form TablesPanel + */ + public TablesPanel() { + + tableModel = new TableTableModel(); + matchesModel = new MatchesTableModel(); + gameChooser = new GameChooser(); + + initComponents(); + // tableModel.setSession(session); + + // formater + timeFormater.setLocale(Locale.ENGLISH); + JustNow jn = timeFormater.getUnit(JustNow.class); + jn.setMaxQuantity(1000L * 30L); // 30 seconds gap (show "just now" from 0 to 30 secs) + + // 1. TABLE CURRENT + tableTables.createDefaultColumnsFromModel(); + activeTablesSorter = new MageTableRowSorter(tableModel); + tableTables.setRowSorter(activeTablesSorter); + + // time ago + tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_CREATED).setCellRenderer(timeAgoCellRenderer); + // skill level + tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_SKILL).setCellRenderer(skillCellRenderer); - // time ago - tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_CREATED).setCellRenderer(timeAgoCellRenderer); /* date sorter (not need, default is good - see getColumnClass) activeTablesSorter.setComparator(TableTableModel.COLUMN_CREATED, new Comparator() { @Override @@ -166,1579 +196,1610 @@ public class TablesPanel extends javax.swing.JPanel { } });*/ - // default sort by created date (last games from above) - ArrayList list = new ArrayList(); - list.add(new RowSorter.SortKey(TableTableModel.COLUMN_CREATED, SortOrder.DESCENDING)); - activeTablesSorter.setSortKeys(list); - - TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER); - - // 2. TABLE COMPLETED - completedTablesSorter = new MageTableRowSorter(matchesModel); - tableCompleted.setRowSorter(completedTablesSorter); - - // duration - tableCompleted.getColumnModel().getColumn(MatchesTableModel.COLUMN_DURATION).setCellRenderer(durationCellRenderer); - // start-end - tableCompleted.getColumnModel().getColumn(MatchesTableModel.COLUMN_START).setCellRenderer(datetimeCellRenderer); - tableCompleted.getColumnModel().getColumn(MatchesTableModel.COLUMN_END).setCellRenderer(datetimeCellRenderer); - // default sort by ended date (last games from above) - ArrayList list2 = new ArrayList(); - list2.add(new RowSorter.SortKey(MatchesTableModel.COLUMN_END, SortOrder.DESCENDING)); - completedTablesSorter.setSortKeys(list2); - - // 3. CHAT - chatPanelMain.getUserChatPanel().useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); - chatPanelMain.getUserChatPanel().setBorder(null); - chatPanelMain.getUserChatPanel().setChatType(ChatPanelBasic.ChatType.TABLES); - - // 4. BUTTONS - filterButtons = new JToggleButton[]{btnStateWaiting, btnStateActive, btnStateFinished, - btnTypeMatch, btnTypeTourneyConstructed, btnTypeTourneyLimited, - btnFormatBlock, btnFormatStandard, btnFormatModern, btnFormatLegacy, btnFormatVintage, btnFormatCommander, btnFormatTinyLeader, btnFormatLimited, btnFormatOther, - btnSkillBeginner, btnSkillCasual, btnSkillSerious, btnRated, btnUnrated, btnOpen, btnPassword}; - - JComponent[] components = new JComponent[]{chatPanelMain, jSplitPane1, jScrollPaneTablesActive, jScrollPaneTablesFinished, jPanelTop, jPanelTables}; - for (JComponent component : components) { - component.setOpaque(false); - } - - jScrollPaneTablesActive.getViewport().setBackground(new Color(255, 255, 255, 50)); - jScrollPaneTablesFinished.getViewport().setBackground(new Color(255, 255, 255, 50)); - - restoreFilters(); - setGUISize(); - - Action openTableAction; - openTableAction = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - int modelRow = Integer.valueOf(e.getActionCommand()); - UUID tableId = (UUID) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 3); - UUID gameId = (UUID) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 2); - String action = (String) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN); - String deckType = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_DECK_TYPE); - boolean isTournament = (Boolean) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 1); - String owner = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_OWNER); - String pwdColumn = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_PASSWORD); - switch (action) { - case "Join": - if (owner.equals(SessionHandler.getUserName()) || owner.startsWith(SessionHandler.getUserName() + ',')) { - try { - JDesktopPane desktopPane = (JDesktopPane) MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE); - JInternalFrame[] windows = desktopPane.getAllFramesInLayer(javax.swing.JLayeredPane.DEFAULT_LAYER); - for (JInternalFrame frame : windows) { - if (frame.getTitle().equals("Waiting for players")) { - frame.toFront(); - frame.setVisible(true); - try { - frame.setSelected(true); - } catch (PropertyVetoException ve) { - LOGGER.error(ve); - } - } - - } - } catch (InterruptedException ex) { - LOGGER.error(ex); - } - return; - } - if (isTournament) { - LOGGER.info("Joining tournament " + tableId); - if (deckType.startsWith("Limited")) { - if (TableTableModel.PASSWORD_VALUE_YES.equals(pwdColumn)) { - joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited")); - } else { - SessionHandler.joinTournamentTable(roomId, tableId, SessionHandler.getUserName(), PlayerType.HUMAN, 1, null, ""); - } - } else { - joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited")); - } - } else { - LOGGER.info("Joining table " + tableId); - joinTableDialog.showDialog(roomId, tableId, false, false); - } - break; - case "Remove": - UserRequestMessage message = new UserRequestMessage("Removing table", "Are you sure you want to remove table?"); - message.setButton1("No", null); - message.setButton2("Yes", PlayerAction.CLIENT_REMOVE_TABLE); - MageFrame.getInstance().showUserRequestDialog(message); - break; - case "Show": - if (isTournament) { - LOGGER.info("Showing tournament table " + tableId); - SessionHandler.watchTable(roomId, tableId); - } - break; - case "Watch": - if (!isTournament) { - LOGGER.info("Watching table " + tableId); - SessionHandler.watchTable(roomId, tableId); - } - break; - case "Replay": - LOGGER.info("Replaying game " + gameId); - SessionHandler.replayGame(gameId); - break; - } - } - }; - - Action closedTableAction; - closedTableAction = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - int modelRow = Integer.valueOf(e.getActionCommand()); - String action = (String) matchesModel.getValueAt(modelRow, MatchesTableModel.COLUMN_ACTION); - switch (action) { - case "Replay": - java.util.List gameList = matchesModel.getListofGames(modelRow); - if (gameList != null && !gameList.isEmpty()) { - if (gameList.size() == 1) { - SessionHandler.replayGame(gameList.get(0)); - } else { - gameChooser.show(gameList, MageFrame.getDesktop().getMousePosition()); - } - } - // MageFrame.getDesktop().showTournament(tournamentId); - break; - case "Show": - if (matchesModel.isTournament(modelRow)) { - LOGGER.info("Showing tournament table " + matchesModel.getTableId(modelRow)); - SessionHandler.watchTable(roomId, matchesModel.getTableId(modelRow)); - } - break; - } - } - }; - - // !!!! adds action buttons to the table panel (don't delete this) - actionButton1 = new ButtonColumn(tableTables, openTableAction, tableTables.convertColumnIndexToView(TableTableModel.ACTION_COLUMN)); - actionButton2 = new ButtonColumn(tableCompleted, closedTableAction, tableCompleted.convertColumnIndexToView(MatchesTableModel.COLUMN_ACTION)); - // !!!! - addTableDoubleClickListener(tableTables, openTableAction); - addTableDoubleClickListener(tableCompleted, closedTableAction); - } - - private void addTableDoubleClickListener(JTable table, Action action) { - table.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - int row = table.convertRowIndexToModel(table.getSelectedRow()); - if (e.getClickCount() == 2 && row != -1) { - action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + row)); - } - } - }); - } - - public void cleanUp() { - saveGuiSettings(); - chatPanelMain.cleanUp(); - } - - public void changeGUISize() { - chatPanelMain.changeGUISize(); - actionButton1.changeGUISize(); - actionButton2.changeGUISize(); - setGUISize(); - } - - private void setGUISize() { - tableTables.getTableHeader().setFont(GUISizeHelper.tableFont); - tableTables.setFont(GUISizeHelper.tableFont); - tableTables.setRowHeight(GUISizeHelper.getTableRowHeight()); - - tableCompleted.getTableHeader().setFont(GUISizeHelper.tableFont); - tableCompleted.setFont(GUISizeHelper.tableFont); - tableCompleted.setRowHeight(GUISizeHelper.getTableRowHeight()); - - jSplitPane1.setDividerSize(GUISizeHelper.dividerBarSize); - jSplitPaneTables.setDividerSize(GUISizeHelper.dividerBarSize); - jScrollPaneTablesActive.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0)); - jScrollPaneTablesActive.getHorizontalScrollBar().setPreferredSize(new Dimension(0, GUISizeHelper.scrollBarSize)); - - ImageIcon icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/state_waiting.png")); - Image img = icon.getImage(); - Image newimg = img.getScaledInstance(GUISizeHelper.menuFont.getSize(), GUISizeHelper.menuFont.getSize(), java.awt.Image.SCALE_SMOOTH); - btnStateWaiting.setIcon(new ImageIcon(newimg)); - - icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/state_active.png")); - img = icon.getImage(); - newimg = img.getScaledInstance(GUISizeHelper.menuFont.getSize(), GUISizeHelper.menuFont.getSize(), java.awt.Image.SCALE_SMOOTH); - btnStateActive.setIcon(new ImageIcon(newimg)); - - icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/state_finished.png")); - img = icon.getImage(); - newimg = img.getScaledInstance(GUISizeHelper.menuFont.getSize(), GUISizeHelper.menuFont.getSize(), java.awt.Image.SCALE_SMOOTH); - btnStateFinished.setIcon(new ImageIcon(newimg)); - - int iconSize = 48 + GUISizeHelper.menuFont.getSize() * 2 - 15; - icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/match_new.png")); - img = icon.getImage(); - newimg = img.getScaledInstance(iconSize, iconSize, java.awt.Image.SCALE_SMOOTH); - btnNewTable.setIcon(new ImageIcon(newimg)); - - icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/tourney_new.png")); - img = icon.getImage(); - newimg = img.getScaledInstance(iconSize, iconSize, java.awt.Image.SCALE_SMOOTH); - btnNewTournament.setIcon(new ImageIcon(newimg)); - - for (JToggleButton component : filterButtons) { - component.setFont(GUISizeHelper.menuFont); - } - Dimension newDimension = new Dimension((int) jPanelBottom.getPreferredSize().getWidth(), GUISizeHelper.menuFont.getSize() + 28); - jPanelBottom.setMinimumSize(newDimension); - jPanelBottom.setPreferredSize(newDimension); - jButtonFooterNext.setFont(GUISizeHelper.menuFont); - jLabelFooterLabel.setFont(new Font(GUISizeHelper.menuFont.getName(), Font.BOLD, GUISizeHelper.menuFont.getSize())); - jLabelFooterText.setFont(GUISizeHelper.menuFont); - } - - private void saveDividerLocations() { - // save divider locations and divider saveDividerLocations - GuiDisplayUtil.saveCurrentBoundsToPrefs(); - GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_1, this.jSplitPane1.getDividerLocation()); - GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_2, this.jSplitPaneTables.getDividerLocation()); - GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_3, chatPanelMain.getSplitDividerLocation()); - } - - private void restoreFilters() { - TableUtil.setActiveFilters(KEY_TABLES_FILTER_SETTINGS, filterButtons); - setTableFilter(); - } - - private void saveGuiSettings() { - TableUtil.saveActiveFiltersToPrefs(KEY_TABLES_FILTER_SETTINGS, filterButtons); - TableUtil.saveColumnWidthAndOrderToPrefs(tableTables, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER); - } - - private void restoreDividers() { - Rectangle currentBounds = MageFrame.getDesktop().getBounds(); - if (currentBounds != null) { - String firstDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_1, null); - String tableDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_2, null); - String chatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_3, null); - GuiDisplayUtil.restoreDividerLocations(currentBounds, firstDivider, jSplitPane1); - GuiDisplayUtil.restoreDividerLocations(currentBounds, tableDivider, jSplitPaneTables); - GuiDisplayUtil.restoreDividerLocations(currentBounds, chatDivider, chatPanelMain); - } - } - - public Map getUIComponents() { - Map components = new HashMap<>(); - - components.put("jScrollPane1", jScrollPaneTablesActive); - components.put("jScrollPane1ViewPort", jScrollPaneTablesActive.getViewport()); - components.put("jPanel1", jPanelTop); - components.put("tablesPanel", this); - - return components; - } - - public void updateTables(Collection tables) { - try { - tableModel.loadData(tables); - this.tableTables.repaint(); - } catch (MageRemoteException ex) { - hideTables(); - } - } - - public void updateMatches(Collection matches) { - try { - matchesModel.loadData(matches); - this.tableCompleted.repaint(); - } catch (MageRemoteException ex) { - hideTables(); - } - } - - public void startTasks() { - if (SessionHandler.getSession() != null) { - if (updateTablesTask == null || updateTablesTask.isDone()) { - updateTablesTask = new UpdateTablesTask(roomId, this); - updateTablesTask.execute(); - } - if (updatePlayersTask == null || updatePlayersTask.isDone()) { - updatePlayersTask = new UpdatePlayersTask(roomId, this.chatPanelMain); - updatePlayersTask.execute(); - } - if (this.btnStateFinished.isSelected()) { - if (updateMatchesTask == null || updateMatchesTask.isDone()) { - updateMatchesTask = new UpdateMatchesTask(roomId, this); - updateMatchesTask.execute(); - } - } else if (updateMatchesTask != null) { - updateMatchesTask.cancel(true); - } - } - } - - public void stopTasks() { - if (updateTablesTask != null) { - updateTablesTask.cancel(true); - } - if (updatePlayersTask != null) { - updatePlayersTask.cancel(true); - } - if (updateMatchesTask != null) { - updateMatchesTask.cancel(true); - } - } - - public void showTables(UUID roomId) { - this.roomId = roomId; - UUID chatRoomId = null; - if (SessionHandler.getSession() != null) { - btnQuickStart.setVisible(SessionHandler.isTestMode()); - gameChooser.init(); - chatRoomId = SessionHandler.getRoomChatId(roomId).orElse(null); - } - if (newTableDialog == null) { - newTableDialog = new NewTableDialog(); - MageFrame.getDesktop().add(newTableDialog, JLayeredPane.MODAL_LAYER); - } - if (newTournamentDialog == null) { - newTournamentDialog = new NewTournamentDialog(); - MageFrame.getDesktop().add(newTournamentDialog, JLayeredPane.MODAL_LAYER); - } - if (joinTableDialog == null) { - joinTableDialog = new JoinTableDialog(); - MageFrame.getDesktop().add(joinTableDialog, JLayeredPane.MODAL_LAYER); - } - if (chatRoomId != null) { - this.chatPanelMain.getUserChatPanel().connect(chatRoomId); - startTasks(); - this.setVisible(true); - this.repaint(); - } else { - hideTables(); - } - //tableModel.setSession(session); - - reloadMessages(); - - MageFrame.getUI().addButton(MageComponents.NEW_GAME_BUTTON, btnNewTable); - - // divider locations have to be set with delay else values set are overwritten with system defaults - Executors.newSingleThreadScheduledExecutor().schedule(() -> restoreDividers(), 300, TimeUnit.MILLISECONDS); - - } - - protected void reloadMessages() { - // reload server messages - java.util.List serverMessages = SessionHandler.getServerMessages(); - synchronized (this) { - this.messages = serverMessages; - this.currentMessage = 0; - } - if (serverMessages.isEmpty()) { - this.jPanelBottom.setVisible(false); - } else { - this.jPanelBottom.setVisible(true); - URLHandler.RemoveMouseAdapter(jLabelFooterText); - URLHandler.handleMessage(serverMessages.get(0), this.jLabelFooterText); - this.jButtonFooterNext.setVisible(serverMessages.size() > 1); - } - } - - public void hideTables() { - this.saveDividerLocations(); - for (Component component : MageFrame.getDesktop().getComponents()) { - if (component instanceof TableWaitingDialog) { - ((TableWaitingDialog) component).closeDialog(); - } - } - stopTasks(); - this.chatPanelMain.getUserChatPanel().disconnect(); - - Component c = this.getParent(); - while (c != null && !(c instanceof TablesPane)) { - c = c.getParent(); - } - if (c != null) { - ((TablesPane) c).hideFrame(); - } - } - - public ChatPanelBasic getChatPanel() { - return chatPanelMain.getUserChatPanel(); - } - - public void setTableFilter() { - // state - java.util.List> stateFilterList = new ArrayList<>(); - if (btnStateWaiting.isSelected()) { - stateFilterList.add(RowFilter.regexFilter("Waiting", TableTableModel.COLUMN_STATUS)); - } - if (btnStateActive.isSelected()) { - stateFilterList.add(RowFilter.regexFilter("Dueling|Constructing|Drafting|Sideboard", TableTableModel.COLUMN_STATUS)); - } - - // type - java.util.List> typeFilterList = new ArrayList<>(); - if (btnTypeMatch.isSelected()) { - typeFilterList.add(RowFilter.regexFilter("Two|Commander|Free|Tiny|Momir", TableTableModel.COLUMN_GAME_TYPE)); - } - if (btnTypeTourneyConstructed.isSelected()) { - typeFilterList.add(RowFilter.regexFilter("Constructed", TableTableModel.COLUMN_GAME_TYPE)); - } - if (btnTypeTourneyLimited.isSelected()) { - typeFilterList.add(RowFilter.regexFilter("Booster|Sealed", TableTableModel.COLUMN_GAME_TYPE)); - } - - // format - java.util.List> formatFilterList = new ArrayList<>(); - if (btnFormatBlock.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Constructed.*Block", TableTableModel.COLUMN_DECK_TYPE)); - } - if (btnFormatStandard.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Constructed - Standard", TableTableModel.COLUMN_DECK_TYPE)); - } - if (btnFormatModern.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Constructed - Modern", TableTableModel.COLUMN_DECK_TYPE)); - } - if (btnFormatLegacy.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Constructed - Legacy", TableTableModel.COLUMN_DECK_TYPE)); - } - if (btnFormatVintage.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Constructed - Vintage", TableTableModel.COLUMN_DECK_TYPE)); - } - if (btnFormatCommander.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander|^Penny Dreadful Commander|^Freeform Commander|^MTGO 1v1 Commander|^Duel Brawl|^Brawl", TableTableModel.COLUMN_DECK_TYPE)); - } - if (btnFormatTinyLeader.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Tiny", TableTableModel.COLUMN_DECK_TYPE)); - } - if (btnFormatLimited.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Limited", TableTableModel.COLUMN_DECK_TYPE)); - } - if (btnFormatOther.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander|^Canadian Highlander|^Constructed - Old", TableTableModel.COLUMN_DECK_TYPE)); - } - - java.util.List> skillFilterList = new ArrayList<>(); - if (btnSkillBeginner.isSelected()) { - skillFilterList.add(RowFilter.regexFilter(SkillLevel.BEGINNER.toString(), TableTableModel.COLUMN_SKILL)); - } - if (btnSkillCasual.isSelected()) { - skillFilterList.add(RowFilter.regexFilter(SkillLevel.CASUAL.toString(), TableTableModel.COLUMN_SKILL)); - } - if (btnSkillSerious.isSelected()) { - skillFilterList.add(RowFilter.regexFilter(SkillLevel.SERIOUS.toString(), TableTableModel.COLUMN_SKILL)); - } - - String ratedMark = TableTableModel.RATED_VALUE_YES; - java.util.List> ratingFilterList = new ArrayList<>(); - if (btnRated.isSelected()) { - // yes word - ratingFilterList.add(RowFilter.regexFilter("^" + ratedMark, TableTableModel.COLUMN_RATING)); - } - if (btnUnrated.isSelected()) { - // not yes word, see https://stackoverflow.com/a/406408/1276632 - ratingFilterList.add(RowFilter.regexFilter("^((?!" + ratedMark + ").)*$", TableTableModel.COLUMN_RATING)); - } - - // Password - String passwordMark = TableTableModel.PASSWORD_VALUE_YES; - java.util.List> passwordFilterList = new ArrayList<>(); - if (btnPassword.isSelected()) { - // yes - passwordFilterList.add(RowFilter.regexFilter("^" + passwordMark, TableTableModel.COLUMN_PASSWORD)); - } - if (btnOpen.isSelected()) { - // no - passwordFilterList.add(RowFilter.regexFilter("^((?!" + passwordMark + ").)*$", TableTableModel.COLUMN_PASSWORD)); - } - - // Hide games of ignored players - java.util.List> ignoreListFilterList = new ArrayList<>(); - String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); - final Set ignoreListCopy = IgnoreList.ignoreList(serverAddress); - if (!ignoreListCopy.isEmpty()) { - ignoreListFilterList.add(new RowFilter() { - @Override - public boolean include(Entry entry) { - final String owner = entry.getStringValue(TableTableModel.COLUMN_OWNER); - return !ignoreListCopy.contains(owner); - } - }); - } - - if (stateFilterList.isEmpty() || typeFilterList.isEmpty() || formatFilterList.isEmpty() - || skillFilterList.isEmpty() || ratingFilterList.isEmpty() - || passwordFilterList.isEmpty()) { // no selection - activeTablesSorter.setRowFilter(RowFilter.regexFilter("Nothing", TableTableModel.COLUMN_SKILL)); - } else { - java.util.List> filterList = new ArrayList<>(); - - if (stateFilterList.size() > 1) { - filterList.add(RowFilter.orFilter(stateFilterList)); - } else if (stateFilterList.size() == 1) { - filterList.addAll(stateFilterList); - } - - if (typeFilterList.size() > 1) { - filterList.add(RowFilter.orFilter(typeFilterList)); - } else if (typeFilterList.size() == 1) { - filterList.addAll(typeFilterList); - } - - if (formatFilterList.size() > 1) { - filterList.add(RowFilter.orFilter(formatFilterList)); - } else if (formatFilterList.size() == 1) { - filterList.addAll(formatFilterList); - } - - if (skillFilterList.size() > 1) { - filterList.add(RowFilter.orFilter(skillFilterList)); - } else if (skillFilterList.size() == 1) { - filterList.addAll(skillFilterList); - } - - if (ratingFilterList.size() > 1) { - filterList.add(RowFilter.orFilter(ratingFilterList)); - } else if (ratingFilterList.size() == 1) { - filterList.addAll(ratingFilterList); - } - - if (passwordFilterList.size() > 1) { - filterList.add(RowFilter.orFilter(passwordFilterList)); - } else if (passwordFilterList.size() == 1) { - filterList.addAll(passwordFilterList); - } - - if (ignoreListFilterList.size() > 1) { - filterList.add(RowFilter.orFilter(ignoreListFilterList)); - } else if (ignoreListFilterList.size() == 1) { - filterList.addAll(ignoreListFilterList); - } - - if (filterList.size() == 1) { - activeTablesSorter.setRowFilter(filterList.get(0)); - } else { - activeTablesSorter.setRowFilter(RowFilter.andFilter(filterList)); - } - } - } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - java.awt.GridBagConstraints gridBagConstraints; - - jPanelTop = new javax.swing.JPanel(); - btnNewTable = new javax.swing.JButton(); - btnNewTournament = new javax.swing.JButton(); - filterBar1 = new javax.swing.JToolBar(); - btnStateWaiting = new javax.swing.JToggleButton(); - btnStateActive = new javax.swing.JToggleButton(); - btnStateFinished = new javax.swing.JToggleButton(); - jSeparator1 = new javax.swing.JToolBar.Separator(); - btnTypeMatch = new javax.swing.JToggleButton(); - btnTypeTourneyConstructed = new javax.swing.JToggleButton(); - btnTypeTourneyLimited = new javax.swing.JToggleButton(); - jSeparator4 = new javax.swing.JToolBar.Separator(); - btnSkillBeginner = new javax.swing.JToggleButton(); - btnSkillCasual = new javax.swing.JToggleButton(); - btnSkillSerious = new javax.swing.JToggleButton(); - jSeparator5 = new javax.swing.JToolBar.Separator(); - btnRated = new javax.swing.JToggleButton(); - btnUnrated = new javax.swing.JToggleButton(); - filterBar2 = new javax.swing.JToolBar(); - btnFormatBlock = new javax.swing.JToggleButton(); - btnFormatStandard = new javax.swing.JToggleButton(); - btnFormatModern = new javax.swing.JToggleButton(); - btnFormatLegacy = new javax.swing.JToggleButton(); - btnFormatVintage = new javax.swing.JToggleButton(); - jSeparator3 = new javax.swing.JToolBar.Separator(); - btnFormatCommander = new javax.swing.JToggleButton(); - btnFormatTinyLeader = new javax.swing.JToggleButton(); - jSeparator2 = new javax.swing.JToolBar.Separator(); - btnFormatLimited = new javax.swing.JToggleButton(); - btnFormatOther = new javax.swing.JToggleButton(); - jSeparator5 = new javax.swing.JToolBar.Separator(); - btnOpen = new javax.swing.JToggleButton(); - btnPassword = new javax.swing.JToggleButton(); - btnQuickStart = new javax.swing.JButton(); - jSplitPane1 = new javax.swing.JSplitPane(); - jPanelTables = new javax.swing.JPanel(); - jSplitPaneTables = new javax.swing.JSplitPane(); - jScrollPaneTablesActive = new javax.swing.JScrollPane(); - tableTables = new javax.swing.JTable(); - jScrollPaneTablesFinished = new javax.swing.JScrollPane(); - tableCompleted = new javax.swing.JTable(); - chatPanelMain = new mage.client.table.PlayersChatPanel(); - jPanelBottom = new javax.swing.JPanel(); - jButtonFooterNext = new javax.swing.JButton(); - jLabelFooterLabel = new javax.swing.JLabel(); - jLabelFooterText = new javax.swing.JLabel(); - - setLayout(new java.awt.GridBagLayout()); - - jPanelTop.setBackground(java.awt.Color.white); - jPanelTop.setOpaque(false); - - btnNewTable.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/match_new.png"))); // NOI18N - btnNewTable.setToolTipText("Creates a new match table."); - btnNewTable.setMargin(new java.awt.Insets(2, 2, 2, 2)); - btnNewTable.addActionListener(evt -> btnNewTableActionPerformed(evt)); - - btnNewTournament.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/tourney_new.png"))); // NOI18N - btnNewTournament.setToolTipText("Creates a new tourney table."); - btnNewTournament.setMargin(new java.awt.Insets(2, 2, 2, 2)); - btnNewTournament.addActionListener(evt -> btnNewTournamentActionPerformed(evt)); - - filterBar1.setFloatable(false); - filterBar1.setForeground(new java.awt.Color(102, 102, 255)); - filterBar1.setFocusable(false); - filterBar1.setOpaque(false); - - btnStateWaiting.setSelected(true); - btnStateWaiting.setToolTipText("Shows all tables waiting for players."); - btnStateWaiting.setActionCommand("stateWait"); - btnStateWaiting.setFocusPainted(false); - btnStateWaiting.setFocusable(false); - btnStateWaiting.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnStateWaiting.setRequestFocusEnabled(false); - btnStateWaiting.setVerifyInputWhenFocusTarget(false); - btnStateWaiting.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnStateWaiting.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnStateWaiting); - - btnStateActive.setSelected(true); - btnStateActive.setToolTipText("Shows all tables with active matches."); - btnStateActive.setActionCommand("stateActive"); - btnStateActive.setFocusPainted(false); - btnStateActive.setFocusable(false); - btnStateActive.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnStateActive.setRequestFocusEnabled(false); - btnStateActive.setVerifyInputWhenFocusTarget(false); - btnStateActive.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnStateActive.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnStateActive); - - btnStateFinished.setSelected(true); - btnStateFinished.setToolTipText("Toggles the visibility of the table of completed
matches and tournaments in the lower area.\n
Showing the last 50 finished matches."); - btnStateFinished.setActionCommand("stateFinished"); - btnStateFinished.setFocusPainted(false); - btnStateFinished.setFocusable(false); - btnStateFinished.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnStateFinished.setRequestFocusEnabled(false); - btnStateFinished.setVerifyInputWhenFocusTarget(false); - btnStateFinished.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnStateFinished.addActionListener(evt -> btnStateFinishedActionPerformed(evt)); - filterBar1.add(btnStateFinished); - filterBar1.add(jSeparator1); - - btnTypeMatch.setSelected(true); - btnTypeMatch.setText("Matches"); - btnTypeMatch.setToolTipText("Shows all non tournament tables."); - btnTypeMatch.setActionCommand("typeMatch"); - btnTypeMatch.setFocusPainted(false); - btnTypeMatch.setFocusable(false); - btnTypeMatch.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnTypeMatch.setRequestFocusEnabled(false); - btnTypeMatch.setVerifyInputWhenFocusTarget(false); - btnTypeMatch.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnTypeMatch.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnTypeMatch); - - btnTypeTourneyConstructed.setSelected(true); - btnTypeTourneyConstructed.setText("Constructed tourn."); - btnTypeTourneyConstructed.setToolTipText("Shows all constructed tournament tables."); - btnTypeTourneyConstructed.setActionCommand("typeTourneyConstructed"); - btnTypeTourneyConstructed.setFocusPainted(false); - btnTypeTourneyConstructed.setFocusable(false); - btnTypeTourneyConstructed.setRequestFocusEnabled(false); - btnTypeTourneyConstructed.setVerifyInputWhenFocusTarget(false); - btnTypeTourneyConstructed.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnTypeTourneyConstructed); - - btnTypeTourneyLimited.setSelected(true); - btnTypeTourneyLimited.setText("Limited tourn."); - btnTypeTourneyLimited.setToolTipText("Shows all limited tournament tables."); - btnTypeTourneyLimited.setActionCommand("typeTourneyLimited"); - btnTypeTourneyLimited.setFocusPainted(false); - btnTypeTourneyLimited.setFocusable(false); - btnTypeTourneyLimited.setMaximumSize(new java.awt.Dimension(72, 20)); - btnTypeTourneyLimited.setRequestFocusEnabled(false); - btnTypeTourneyLimited.setVerifyInputWhenFocusTarget(false); - btnTypeTourneyLimited.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnTypeTourneyLimited); - filterBar1.add(jSeparator4); - - btnSkillBeginner.setSelected(true); - btnSkillBeginner.setText("Beginner"); - btnSkillBeginner.setToolTipText("Shows all tables with skill level beginner."); - btnSkillBeginner.setActionCommand("typeMatch"); - btnSkillBeginner.setFocusPainted(false); - btnSkillBeginner.setFocusable(false); - btnSkillBeginner.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnSkillBeginner.setRequestFocusEnabled(false); - btnSkillBeginner.setVerifyInputWhenFocusTarget(false); - btnSkillBeginner.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnSkillBeginner.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnSkillBeginner); - - btnSkillCasual.setSelected(true); - btnSkillCasual.setText("Casual"); - btnSkillCasual.setToolTipText("Shows all tables with skill level casual."); - btnSkillCasual.setActionCommand("typeMatch"); - btnSkillCasual.setFocusPainted(false); - btnSkillCasual.setFocusable(false); - btnSkillCasual.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnSkillCasual.setRequestFocusEnabled(false); - btnSkillCasual.setVerifyInputWhenFocusTarget(false); - btnSkillCasual.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnSkillCasual.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnSkillCasual); - - btnSkillSerious.setSelected(true); - btnSkillSerious.setText("Serious"); - btnSkillSerious.setToolTipText("Shows all tables with skill level serious."); - btnSkillSerious.setActionCommand("typeMatch"); - btnSkillSerious.setFocusPainted(false); - btnSkillSerious.setFocusable(false); - btnSkillSerious.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnSkillSerious.setRequestFocusEnabled(false); - btnSkillSerious.setVerifyInputWhenFocusTarget(false); - btnSkillSerious.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnSkillSerious.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnSkillSerious); - - filterBar1.add(jSeparator4); - - btnRated.setSelected(true); - btnRated.setText("Rated"); - btnRated.setToolTipText("Shows all rated tables."); - btnRated.setFocusPainted(false); - btnRated.setFocusable(false); - btnRated.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnRated.setRequestFocusEnabled(false); - btnRated.setVerifyInputWhenFocusTarget(false); - btnRated.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnRated.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnRated); - - btnUnrated.setSelected(true); - btnUnrated.setText("Unrated"); - btnUnrated.setToolTipText("Shows all unrated tables."); - btnUnrated.setFocusPainted(false); - btnUnrated.setFocusable(false); - btnUnrated.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnUnrated.setRequestFocusEnabled(false); - btnUnrated.setVerifyInputWhenFocusTarget(false); - btnUnrated.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnUnrated.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar1.add(btnUnrated); - - // second filter line - filterBar2.setFloatable(false); - filterBar2.setFocusable(false); - filterBar2.setOpaque(false); - - btnFormatBlock.setSelected(true); - btnFormatBlock.setText("Block"); - btnFormatBlock.setToolTipText("Block constructed formats."); - btnFormatBlock.setFocusPainted(false); - btnFormatBlock.setFocusable(false); - btnFormatBlock.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnFormatBlock.setRequestFocusEnabled(false); - btnFormatBlock.setVerifyInputWhenFocusTarget(false); - btnFormatBlock.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnFormatBlock.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatBlock); - - btnFormatStandard.setSelected(true); - btnFormatStandard.setText("Standard"); - btnFormatStandard.setToolTipText("Standard format."); - btnFormatStandard.setFocusPainted(false); - btnFormatStandard.setFocusable(false); - btnFormatStandard.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnFormatStandard.setRequestFocusEnabled(false); - btnFormatStandard.setVerifyInputWhenFocusTarget(false); - btnFormatStandard.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnFormatStandard.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatStandard); - - btnFormatModern.setSelected(true); - btnFormatModern.setText("Modern"); - btnFormatModern.setToolTipText("Modern format."); - btnFormatModern.setFocusPainted(false); - btnFormatModern.setFocusable(false); - btnFormatModern.setRequestFocusEnabled(false); - btnFormatModern.setVerifyInputWhenFocusTarget(false); - btnFormatModern.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatModern); - - btnFormatLegacy.setSelected(true); - btnFormatLegacy.setText("Legacy"); - btnFormatLegacy.setToolTipText("Legacy format."); - btnFormatLegacy.setFocusPainted(false); - btnFormatLegacy.setFocusable(false); - btnFormatLegacy.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnFormatLegacy.setRequestFocusEnabled(false); - btnFormatLegacy.setVerifyInputWhenFocusTarget(false); - btnFormatLegacy.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnFormatLegacy.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatLegacy); - - btnFormatVintage.setSelected(true); - btnFormatVintage.setText("Vintage"); - btnFormatVintage.setToolTipText("Vintage format."); - btnFormatVintage.setFocusPainted(false); - btnFormatVintage.setFocusable(false); - btnFormatVintage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnFormatVintage.setRequestFocusEnabled(false); - btnFormatVintage.setVerifyInputWhenFocusTarget(false); - btnFormatVintage.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnFormatVintage.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatVintage); - filterBar2.add(jSeparator3); - - btnFormatCommander.setSelected(true); - btnFormatCommander.setText("Commander"); - btnFormatCommander.setToolTipText("Commander format."); - btnFormatCommander.setFocusPainted(false); - btnFormatCommander.setFocusable(false); - btnFormatCommander.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnFormatCommander.setRequestFocusEnabled(false); - btnFormatCommander.setVerifyInputWhenFocusTarget(false); - btnFormatCommander.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnFormatCommander.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatCommander); - - btnFormatTinyLeader.setSelected(true); - btnFormatTinyLeader.setText("Tiny Leader"); - btnFormatTinyLeader.setToolTipText("Tiny Leader format."); - btnFormatTinyLeader.setFocusPainted(false); - btnFormatTinyLeader.setFocusable(false); - btnFormatTinyLeader.setRequestFocusEnabled(false); - btnFormatTinyLeader.setVerifyInputWhenFocusTarget(false); - btnFormatTinyLeader.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatTinyLeader); - filterBar2.add(jSeparator2); - - btnFormatLimited.setSelected(true); - btnFormatLimited.setText("Limited"); - btnFormatLimited.setToolTipText("Limited format."); - btnFormatLimited.setFocusPainted(false); - btnFormatLimited.setFocusable(false); - btnFormatLimited.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnFormatLimited.setRequestFocusEnabled(false); - btnFormatLimited.setVerifyInputWhenFocusTarget(false); - btnFormatLimited.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnFormatLimited.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatLimited); - - btnFormatOther.setSelected(true); - btnFormatOther.setText("Other"); - btnFormatOther.setToolTipText("Other formats (Freeform, Pauper, Extended, etc.)"); - btnFormatOther.setFocusPainted(false); - btnFormatOther.setFocusable(false); - btnFormatOther.setRequestFocusEnabled(false); - btnFormatOther.setVerifyInputWhenFocusTarget(false); - btnFormatOther.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnFormatOther); - filterBar2.add(jSeparator5); - - btnOpen.setSelected(true); - btnOpen.setText("Open"); - btnOpen.setToolTipText("Show open games"); - btnOpen.setFocusPainted(false); - btnOpen.setFocusable(false); - btnOpen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnOpen.setRequestFocusEnabled(false); - btnOpen.setVerifyInputWhenFocusTarget(false); - btnOpen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnOpen.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnOpen); - - btnPassword.setSelected(true); - btnPassword.setText("PW"); - btnPassword.setToolTipText("Show passworded games"); - btnPassword.setFocusPainted(false); - btnPassword.setFocusable(false); - btnPassword.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnPassword.setRequestFocusEnabled(false); - btnPassword.setVerifyInputWhenFocusTarget(false); - btnPassword.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnPassword.addActionListener(evt -> btnFilterActionPerformed(evt)); - filterBar2.add(btnPassword); - - btnQuickStart.setText("Quick Start"); - btnQuickStart.setFocusable(false); - btnQuickStart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnQuickStart.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnQuickStart.addActionListener(evt -> btnQuickStartActionPerformed(evt)); - - javax.swing.GroupLayout jPanelTopLayout = new javax.swing.GroupLayout(jPanelTop); - jPanelTop.setLayout(jPanelTopLayout); - jPanelTopLayout.setHorizontalGroup( - jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanelTopLayout.createSequentialGroup() - .addContainerGap() - .addComponent(btnNewTable) - .addGap(6, 6, 6) - .addComponent(btnNewTournament) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 491, Short.MAX_VALUE) - .addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnQuickStart) - .addContainerGap(835, Short.MAX_VALUE)) - ); - jPanelTopLayout.setVerticalGroup( - jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanelTopLayout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btnNewTable) - .addComponent(btnNewTournament)) - .addGroup(jPanelTopLayout.createSequentialGroup() - .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnQuickStart)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addContainerGap()) - ); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; - add(jPanelTop, gridBagConstraints); - - jSplitPane1.setBorder(null); - jSplitPane1.setDividerSize(10); - jSplitPane1.setResizeWeight(1.0); - - jSplitPaneTables.setBorder(null); - jSplitPaneTables.setDividerSize(10); - jSplitPaneTables.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - jSplitPaneTables.setResizeWeight(0.5); - - jScrollPaneTablesActive.setBorder(null); - jScrollPaneTablesActive.setViewportBorder(null); - - tableTables.setModel(this.tableModel); - jScrollPaneTablesActive.setViewportView(tableTables); - - jSplitPaneTables.setLeftComponent(jScrollPaneTablesActive); - - jScrollPaneTablesFinished.setBorder(null); - jScrollPaneTablesFinished.setViewportBorder(null); - jScrollPaneTablesFinished.setMinimumSize(new java.awt.Dimension(23, 0)); - - tableCompleted.setModel(this.matchesModel); - jScrollPaneTablesFinished.setViewportView(tableCompleted); - - jSplitPaneTables.setRightComponent(jScrollPaneTablesFinished); - - javax.swing.GroupLayout jPanelTablesLayout = new javax.swing.GroupLayout(jPanelTables); - jPanelTables.setLayout(jPanelTablesLayout); - jPanelTablesLayout.setHorizontalGroup( - jPanelTablesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSplitPaneTables, javax.swing.GroupLayout.PREFERRED_SIZE, 23, Short.MAX_VALUE) - ); - jPanelTablesLayout.setVerticalGroup( - jPanelTablesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSplitPaneTables, javax.swing.GroupLayout.DEFAULT_SIZE, 672, Short.MAX_VALUE) - ); - - jSplitPane1.setLeftComponent(jPanelTables); - jSplitPane1.setRightComponent(chatPanelMain); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridy = 1; - gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 1.0; - add(jSplitPane1, gridBagConstraints); - - jPanelBottom.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); - jPanelBottom.setPreferredSize(new java.awt.Dimension(516, 37)); - jPanelBottom.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); - - jButtonFooterNext.setText("Next"); - jButtonFooterNext.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - jButtonFooterNext.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - jButtonFooterNext.setOpaque(false); - jButtonFooterNext.addActionListener(evt -> jButtonFooterNextActionPerformed(evt)); - jPanelBottom.add(jButtonFooterNext); - - jLabelFooterLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N - jLabelFooterLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - jLabelFooterLabel.setText("Message of the Day:"); - jLabelFooterLabel.setAlignmentY(0.3F); - jPanelBottom.add(jLabelFooterLabel); - - jLabelFooterText.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - jLabelFooterText.setText("You are playing Mage version 0.7.5. Welcome! -- Mage dev team --"); - jPanelBottom.add(jLabelFooterText); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridy = 2; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; - add(jPanelBottom, gridBagConstraints); - }//
//GEN-END:initComponents - - private void btnNewTournamentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTournamentActionPerformed - newTournamentDialog.showDialog(roomId); -}//GEN-LAST:event_btnNewTournamentActionPerformed - - private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed - TableView table; - try { - File f = new File("test.dck"); - if (!f.exists()) { - JOptionPane.showMessageDialog(null, "Couldn't find test.dck file for quick game start", "Error", JOptionPane.ERROR_MESSAGE); - return; - } - - MatchOptions options = new MatchOptions("1", "Two Player Duel", false, 2); - options.getPlayerTypes().add(PlayerType.HUMAN); - options.getPlayerTypes().add(PlayerType.COMPUTER_MAD); - options.setDeckType("Limited"); - options.setAttackOption(MultiplayerAttackOption.LEFT); - options.setRange(RangeOfInfluence.ALL); - options.setWinsNeeded(1); - options.setMatchTimeLimit(MatchTimeLimit.NONE); - options.setFreeMulligans(2); - options.setSkillLevel(SkillLevel.CASUAL); - options.setRollbackTurnsAllowed(true); - options.setQuitRatio(100); - String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); - options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); - table = SessionHandler.createTable(roomId, options); - - SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, DeckImporterUtil.importDeck("test.dck"), ""); - SessionHandler.joinTable(roomId, table.getTableId(), "Computer", PlayerType.COMPUTER_MAD, 5, DeckImporterUtil.importDeck("test.dck"), ""); - SessionHandler.startMatch(roomId, table.getTableId()); - } catch (HeadlessException ex) { - handleError(ex); - } -}//GEN-LAST:event_btnQuickStartActionPerformed - - private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed - newTableDialog.showDialog(roomId); - }//GEN-LAST:event_btnNewTableActionPerformed - - private void jButtonFooterNextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonFooterNextActionPerformed - synchronized (this) { - if (messages != null && !messages.isEmpty()) { - currentMessage++; - if (currentMessage >= messages.size()) { - currentMessage = 0; - } - - URLHandler.RemoveMouseAdapter(jLabelFooterText); - URLHandler.handleMessage(messages.get(currentMessage), this.jLabelFooterText); - } - } - }//GEN-LAST:event_jButtonFooterNextActionPerformed - - private void btnFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFilterActionPerformed - setTableFilter(); - }//GEN-LAST:event_btnFilterActionPerformed - - private void btnStateFinishedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStateFinishedActionPerformed - if (this.btnStateFinished.isSelected()) { - this.jSplitPaneTables.setDividerLocation(-1); - } else { - this.jSplitPaneTables.setDividerLocation(this.jPanelTables.getHeight()); - } - this.startTasks(); - }//GEN-LAST:event_btnStateFinishedActionPerformed - - private void handleError(Exception ex) { - LOGGER.fatal("Error loading deck: ", ex); - JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE); - } - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JToggleButton btnFormatBlock; - private javax.swing.JToggleButton btnFormatCommander; - private javax.swing.JToggleButton btnFormatLegacy; - private javax.swing.JToggleButton btnFormatLimited; - private javax.swing.JToggleButton btnFormatModern; - private javax.swing.JToggleButton btnFormatOther; - private javax.swing.JToggleButton btnFormatStandard; - private javax.swing.JToggleButton btnFormatTinyLeader; - private javax.swing.JToggleButton btnFormatVintage; - private javax.swing.JButton btnNewTable; - private javax.swing.JButton btnNewTournament; - private javax.swing.JToggleButton btnOpen; - private javax.swing.JToggleButton btnPassword; - private javax.swing.JButton btnQuickStart; - private javax.swing.JToggleButton btnSkillBeginner; - private javax.swing.JToggleButton btnSkillCasual; - private javax.swing.JToggleButton btnSkillSerious; - private javax.swing.JToggleButton btnRated; - private javax.swing.JToggleButton btnUnrated; - private javax.swing.JToggleButton btnStateActive; - private javax.swing.JToggleButton btnStateFinished; - private javax.swing.JToggleButton btnStateWaiting; - private javax.swing.JToggleButton btnTypeMatch; - private javax.swing.JToggleButton btnTypeTourneyConstructed; - private javax.swing.JToggleButton btnTypeTourneyLimited; - private mage.client.table.PlayersChatPanel chatPanelMain; - private javax.swing.JToolBar filterBar1; - private javax.swing.JToolBar filterBar2; - private javax.swing.JButton jButtonFooterNext; - private javax.swing.JLabel jLabelFooterLabel; - private javax.swing.JLabel jLabelFooterText; - private javax.swing.JPanel jPanelBottom; - private javax.swing.JPanel jPanelTables; - private javax.swing.JPanel jPanelTop; - private javax.swing.JScrollPane jScrollPaneTablesActive; - private javax.swing.JScrollPane jScrollPaneTablesFinished; - private javax.swing.JToolBar.Separator jSeparator1; - private javax.swing.JToolBar.Separator jSeparator2; - private javax.swing.JToolBar.Separator jSeparator3; - private javax.swing.JToolBar.Separator jSeparator4; - private javax.swing.JToolBar.Separator jSeparator5; - private javax.swing.JSplitPane jSplitPane1; - private javax.swing.JSplitPane jSplitPaneTables; - private javax.swing.JTable tableCompleted; - private javax.swing.JTable tableTables; - // End of variables declaration//GEN-END:variables - -} - -class TableTableModel extends AbstractTableModel { - - final ImageIcon tourneyIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/tourney_icon.png")); - final ImageIcon matchIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/match_icon.png")); - - public static final int COLUMN_ICON = 0; - public static final int COLUMN_DECK_TYPE = 1; // column the deck type is located (starting with 0) Start string is used to check for Limited - public static final int COLUMN_OWNER = 2; - public static final int COLUMN_GAME_TYPE = 3; - public static final int COLUMN_INFO = 4; - public static final int COLUMN_STATUS = 5; - public static final int COLUMN_PASSWORD = 6; - public static final int COLUMN_CREATED = 7; - public static final int COLUMN_SKILL = 8; - public static final int COLUMN_RATING = 9; - public static final int COLUMN_QUIT_RATIO = 10; - public static final int ACTION_COLUMN = 11; // column the action is located (starting with 0) - - public static final String RATED_VALUE_YES = "YES"; - public static final String RATED_VALUE_NO = ""; - - public static final String PASSWORD_VALUE_YES = "YES"; - - private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rating", "Quit %", "Action"}; - - private TableView[] tables = new TableView[0]; - - TableTableModel() { - } - - public void loadData(Collection tables) throws MageRemoteException { - this.tables = tables.toArray(new TableView[0]); - this.fireTableDataChanged(); - } - - @Override - public int getRowCount() { - return tables.length; - } - - @Override - public int getColumnCount() { - return columnNames.length; - } - - @Override - public Object getValueAt(int arg0, int arg1) { - switch (arg1) { - case 0: - return tables[arg0].isTournament() ? tourneyIcon : matchIcon; - case 1: - return tables[arg0].getDeckType(); - case 2: - return tables[arg0].getControllerName(); - case 3: - return tables[arg0].getGameType(); - case 4: - return tables[arg0].getAdditionalInfo(); - case 5: - return tables[arg0].getTableStateText(); - case 6: - return tables[arg0].isPassworded() ? PASSWORD_VALUE_YES : ""; - case 7: - return tables[arg0].getCreateTime(); // use cell render, not format here - case 8: - return tables[arg0].getSkillLevel(); - case 9: - return tables[arg0].isRated() ? RATED_VALUE_YES : RATED_VALUE_NO; - case 10: - return tables[arg0].getQuitRatio(); - case 11: - switch (tables[arg0].getTableState()) { - - case WAITING: - String owner = tables[arg0].getControllerName(); - if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) { - return ""; - } - return "Join"; - case CONSTRUCTING: - case DRAFTING: - if (tables[arg0].isTournament()) { - return "Show"; - } - case DUELING: - if (tables[arg0].isTournament()) { - return "Show"; - } else { - owner = tables[arg0].getControllerName(); - if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) { - return ""; - } - if (tables[arg0].getSpectatorsAllowed()) { - return "Watch"; - } - return ""; - } - default: - return ""; - } - case 12: - return tables[arg0].isTournament(); - case 13: - if (!tables[arg0].getGames().isEmpty()) { - return tables[arg0].getGames().get(0); - } - return null; - case 14: - return tables[arg0].getTableId(); - } - return ""; - } - - @Override - public String getColumnName(int columnIndex) { - String colName = ""; - - if (columnIndex <= getColumnCount()) { - colName = columnNames[columnIndex]; - } - - return colName; - } - - @Override - public Class getColumnClass(int columnIndex) { - switch (columnIndex) { - case COLUMN_ICON: - return Icon.class; - case COLUMN_SKILL: - return SkillLevel.class; - case COLUMN_CREATED: - return Date.class; - default: - return String.class; - } - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return columnIndex == ACTION_COLUMN; - } - -} - -class UpdateTablesTask extends SwingWorker> { - - private final UUID roomId; - private final TablesPanel panel; - - private static final Logger logger = Logger.getLogger(UpdateTablesTask.class); - - private int count = 0; - - UpdateTablesTask(UUID roomId, TablesPanel panel) { - - this.roomId = roomId; - this.panel = panel; - } - - @Override - protected Void doInBackground() throws Exception { - while (!isCancelled()) { - Collection tables = SessionHandler.getTables(roomId); - if (tables != null) { - this.publish(tables); - } - TimeUnit.SECONDS.sleep(3); - } - return null; - } - - @Override - protected void process(java.util.List> view) { - panel.updateTables(view.get(0)); - count++; - if (count > 60) { - count = 0; - panel.reloadMessages(); - } - } - - @Override - protected void done() { - try { - get(); - } catch (InterruptedException | ExecutionException ex) { - logger.fatal("Update Tables Task error", ex); - } catch (CancellationException ex) { - } - } - -} - -class UpdatePlayersTask extends SwingWorker> { - - private final UUID roomId; - private final PlayersChatPanel chat; - - private static final Logger logger = Logger.getLogger(UpdatePlayersTask.class); - - UpdatePlayersTask(UUID roomId, PlayersChatPanel chat) { - - this.roomId = roomId; - this.chat = chat; - } - - @Override - protected Void doInBackground() throws Exception { - while (!isCancelled()) { - this.publish(SessionHandler.getRoomUsers(roomId)); - TimeUnit.SECONDS.sleep(3); - } - return null; - } - - @Override - protected void process(java.util.List> roomUserInfo) { - chat.setRoomUserInfo(roomUserInfo); - } - - @Override - protected void done() { - try { - get(); - } catch (InterruptedException | ExecutionException ex) { - logger.fatal("Update Players Task error", ex); - } catch (CancellationException ex) { - } - } - -} - -class MatchesTableModel extends AbstractTableModel { - - private final String[] columnNames = new String[]{"Deck Type", "Players", "Game Type", "Rating", "Result", "Duration", "Start Time", "End Time", "Action"}; - public static final int COLUMN_DURATION = 5; - public static final int COLUMN_START = 6; - public static final int COLUMN_END = 7; - public static final int COLUMN_ACTION = 8; // column the action is located (starting with 0) - - private MatchView[] matches = new MatchView[0]; - - public void loadData(Collection matches) throws MageRemoteException { - this.matches = matches.toArray(new MatchView[0]); - this.fireTableDataChanged(); - } - - MatchesTableModel() { - } - - @Override - public int getRowCount() { - return matches.length; - } - - @Override - public int getColumnCount() { - return columnNames.length; - } - - @Override - public Object getValueAt(int arg0, int arg1) { - switch (arg1) { - case 0: - return matches[arg0].getDeckType(); - case 1: - return matches[arg0].getPlayers(); - case 2: - return matches[arg0].getGameType(); - case 3: - return matches[arg0].isRated() ? TableTableModel.RATED_VALUE_YES : TableTableModel.RATED_VALUE_NO; - case 4: - return matches[arg0].getResult(); - case 5: - if (matches[arg0].getEndTime() != null) { - return matches[arg0].getEndTime().getTime() - matches[arg0].getStartTime().getTime() + new Date().getTime(); - } else { - return 0L; - } - case 6: - return matches[arg0].getStartTime(); - case 7: - return matches[arg0].getEndTime(); - case 8: - if (matches[arg0].isTournament()) { - return "Show"; - } else if (matches[arg0].isReplayAvailable()) { - return "Replay"; - } else { - return "None"; - } - case 9: - return matches[arg0].getGames(); - } - return ""; - } - - public java.util.List getListofGames(int row) { - return matches[row].getGames(); - } - - public boolean isTournament(int row) { - return matches[row].isTournament(); - } - - public UUID getMatchId(int row) { - return matches[row].getMatchId(); - } - - public UUID getTableId(int row) { - return matches[row].getTableId(); - } - - @Override - public String getColumnName(int columnIndex) { - String colName = ""; - - if (columnIndex <= getColumnCount()) { - colName = columnNames[columnIndex]; - } - - return colName; - } - - @Override - public Class getColumnClass(int columnIndex) { - switch (columnIndex) { - case COLUMN_DURATION: - return Long.class; - case COLUMN_START: - return Date.class; - case COLUMN_END: - return Date.class; - default: - return String.class; - } - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return columnIndex == COLUMN_ACTION; - } - -} - -class UpdateMatchesTask extends SwingWorker> { - - private final UUID roomId; - private final TablesPanel panel; - - private static final Logger logger = Logger.getLogger(UpdateTablesTask.class); - - UpdateMatchesTask(UUID roomId, TablesPanel panel) { - this.roomId = roomId; - this.panel = panel; - } - - @Override - protected Void doInBackground() throws Exception { - while (!isCancelled()) { - Collection matches = SessionHandler.getFinishedMatches(roomId); - if (!matches.isEmpty()) { - this.publish(matches); - } - TimeUnit.SECONDS.sleep(10); - } - return null; - } - - @Override - protected void process(java.util.List> view) { - panel.updateMatches(view.get(0)); - } - - @Override - protected void done() { - try { - get(); - } catch (InterruptedException | ExecutionException ex) { - logger.fatal("Update Matches Task error", ex); - } catch (CancellationException ex) { - } - } - -} - -class GameChooser extends JPopupMenu { - - public void init() { - - } - - public void show(java.util.List games, Point p) { - if (p == null) { - return; - } - this.removeAll(); - for (UUID gameId : games) { - this.add(new GameChooserAction(gameId, gameId.toString())); - } - this.show(MageFrame.getDesktop(), p.x, p.y); - GuiDisplayUtil.keepComponentInsideScreen(p.x, p.y, this); - } - - private class GameChooserAction extends AbstractAction { - - private final UUID id; - - public GameChooserAction(UUID id, String choice) { - this.id = id; - putValue(Action.NAME, choice); - } - - @Override - public void actionPerformed(ActionEvent e) { - SessionHandler.replayGame(id); - setVisible(false); - } - - } - -} + // default sort by created date (last games from above) + ArrayList list = new ArrayList(); + list.add(new RowSorter.SortKey(TableTableModel.COLUMN_CREATED, SortOrder.DESCENDING)); + activeTablesSorter.setSortKeys(list); + + TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER); + + // 2. TABLE COMPLETED + completedTablesSorter = new MageTableRowSorter(matchesModel); + tableCompleted.setRowSorter(completedTablesSorter); + + // duration + tableCompleted.getColumnModel().getColumn(MatchesTableModel.COLUMN_DURATION).setCellRenderer(durationCellRenderer); + // start-end + tableCompleted.getColumnModel().getColumn(MatchesTableModel.COLUMN_START).setCellRenderer(datetimeCellRenderer); + tableCompleted.getColumnModel().getColumn(MatchesTableModel.COLUMN_END).setCellRenderer(datetimeCellRenderer); + // default sort by ended date (last games from above) + ArrayList list2 = new ArrayList(); + list2.add(new RowSorter.SortKey(MatchesTableModel.COLUMN_END, SortOrder.DESCENDING)); + completedTablesSorter.setSortKeys(list2); + + // 3. CHAT + chatPanelMain.getUserChatPanel().useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); + chatPanelMain.getUserChatPanel().setBorder(null); + chatPanelMain.getUserChatPanel().setChatType(ChatPanelBasic.ChatType.TABLES); + + // 4. BUTTONS + filterButtons = new JToggleButton[]{btnStateWaiting, btnStateActive, btnStateFinished, + btnTypeMatch, btnTypeTourneyConstructed, btnTypeTourneyLimited, + btnFormatBlock, btnFormatStandard, btnFormatModern, btnFormatLegacy, btnFormatVintage, btnFormatCommander, btnFormatTinyLeader, btnFormatLimited, btnFormatOther, + btnSkillBeginner, btnSkillCasual, btnSkillSerious, btnRated, btnUnrated, btnOpen, btnPassword}; + + JComponent[] components = new JComponent[]{chatPanelMain, jSplitPane1, jScrollPaneTablesActive, jScrollPaneTablesFinished, jPanelTop, jPanelTables}; + for (JComponent component : components) { + component.setOpaque(false); + } + + jScrollPaneTablesActive.getViewport().setBackground(new Color(255, 255, 255, 50)); + jScrollPaneTablesFinished.getViewport().setBackground(new Color(255, 255, 255, 50)); + + restoreFilters(); + setGUISize(); + + Action openTableAction; + openTableAction = new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + int modelRow = Integer.valueOf(e.getActionCommand()); + UUID tableId = (UUID) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 3); + UUID gameId = (UUID) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 2); + String action = (String) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN); + String deckType = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_DECK_TYPE); + boolean isTournament = (Boolean) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 1); + String owner = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_OWNER); + String pwdColumn = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_PASSWORD); + switch (action) { + case "Join": + if (owner.equals(SessionHandler.getUserName()) || owner.startsWith(SessionHandler.getUserName() + ',')) { + try { + JDesktopPane desktopPane = (JDesktopPane) MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE); + JInternalFrame[] windows = desktopPane.getAllFramesInLayer(javax.swing.JLayeredPane.DEFAULT_LAYER); + for (JInternalFrame frame : windows) { + if (frame.getTitle().equals("Waiting for players")) { + frame.toFront(); + frame.setVisible(true); + try { + frame.setSelected(true); + } catch (PropertyVetoException ve) { + LOGGER.error(ve); + } + } + + } + } catch (InterruptedException ex) { + LOGGER.error(ex); + } + return; + } + if (isTournament) { + LOGGER.info("Joining tournament " + tableId); + if (deckType.startsWith("Limited")) { + if (TableTableModel.PASSWORD_VALUE_YES.equals(pwdColumn)) { + joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited")); + } else { + SessionHandler.joinTournamentTable(roomId, tableId, SessionHandler.getUserName(), PlayerType.HUMAN, 1, null, ""); + } + } else { + joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited")); + } + } else { + LOGGER.info("Joining table " + tableId); + joinTableDialog.showDialog(roomId, tableId, false, false); + } + break; + case "Remove": + UserRequestMessage message = new UserRequestMessage("Removing table", "Are you sure you want to remove table?"); + message.setButton1("No", null); + message.setButton2("Yes", PlayerAction.CLIENT_REMOVE_TABLE); + MageFrame.getInstance().showUserRequestDialog(message); + break; + case "Show": + if (isTournament) { + LOGGER.info("Showing tournament table " + tableId); + SessionHandler.watchTable(roomId, tableId); + } + break; + case "Watch": + if (!isTournament) { + LOGGER.info("Watching table " + tableId); + SessionHandler.watchTable(roomId, tableId); + } + break; + case "Replay": + LOGGER.info("Replaying game " + gameId); + SessionHandler.replayGame(gameId); + break; + } + } + }; + + Action closedTableAction; + closedTableAction = new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + int modelRow = Integer.valueOf(e.getActionCommand()); + String action = (String) matchesModel.getValueAt(modelRow, MatchesTableModel.COLUMN_ACTION); + switch (action) { + case "Replay": + java.util.List gameList = matchesModel.getListofGames(modelRow); + if (gameList != null && !gameList.isEmpty()) { + if (gameList.size() == 1) { + SessionHandler.replayGame(gameList.get(0)); + } else { + gameChooser.show(gameList, MageFrame.getDesktop().getMousePosition()); + } + } + // MageFrame.getDesktop().showTournament(tournamentId); + break; + case "Show": + if (matchesModel.isTournament(modelRow)) { + LOGGER.info("Showing tournament table " + matchesModel.getTableId(modelRow)); + SessionHandler.watchTable(roomId, matchesModel.getTableId(modelRow)); + } + break; + } + } + }; + + // !!!! adds action buttons to the table panel (don't delete this) + actionButton1 = new ButtonColumn(tableTables, openTableAction, tableTables.convertColumnIndexToView(TableTableModel.ACTION_COLUMN)); + actionButton2 = new ButtonColumn(tableCompleted, closedTableAction, tableCompleted.convertColumnIndexToView(MatchesTableModel.COLUMN_ACTION)); + // !!!! + addTableDoubleClickListener(tableTables, openTableAction); + addTableDoubleClickListener(tableCompleted, closedTableAction); + } + + private void addTableDoubleClickListener(JTable table, Action action) { + table.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + int selRow = table.getSelectedRow(); + if (selRow != -1) { + int dataRow = table.convertRowIndexToModel(selRow); + if (dataRow != -1) { + action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + dataRow)); + } + } + } + } + }); + } + + public void cleanUp() { + saveGuiSettings(); + chatPanelMain.cleanUp(); + } + + public void changeGUISize() { + chatPanelMain.changeGUISize(); + actionButton1.changeGUISize(); + actionButton2.changeGUISize(); + setGUISize(); + } + + private void setGUISize() { + tableTables.getTableHeader().setFont(GUISizeHelper.tableFont); + tableTables.setFont(GUISizeHelper.tableFont); + tableTables.setRowHeight(GUISizeHelper.getTableRowHeight()); + + tableCompleted.getTableHeader().setFont(GUISizeHelper.tableFont); + tableCompleted.setFont(GUISizeHelper.tableFont); + tableCompleted.setRowHeight(GUISizeHelper.getTableRowHeight()); + + jSplitPane1.setDividerSize(GUISizeHelper.dividerBarSize); + jSplitPaneTables.setDividerSize(GUISizeHelper.dividerBarSize); + jScrollPaneTablesActive.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0)); + jScrollPaneTablesActive.getHorizontalScrollBar().setPreferredSize(new Dimension(0, GUISizeHelper.scrollBarSize)); + + ImageIcon icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/state_waiting.png")); + Image img = icon.getImage(); + Image newimg = img.getScaledInstance(GUISizeHelper.menuFont.getSize(), GUISizeHelper.menuFont.getSize(), java.awt.Image.SCALE_SMOOTH); + btnStateWaiting.setIcon(new ImageIcon(newimg)); + + icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/state_active.png")); + img = icon.getImage(); + newimg = img.getScaledInstance(GUISizeHelper.menuFont.getSize(), GUISizeHelper.menuFont.getSize(), java.awt.Image.SCALE_SMOOTH); + btnStateActive.setIcon(new ImageIcon(newimg)); + + icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/state_finished.png")); + img = icon.getImage(); + newimg = img.getScaledInstance(GUISizeHelper.menuFont.getSize(), GUISizeHelper.menuFont.getSize(), java.awt.Image.SCALE_SMOOTH); + btnStateFinished.setIcon(new ImageIcon(newimg)); + + int iconSize = 48 + GUISizeHelper.menuFont.getSize() * 2 - 15; + icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/match_new.png")); + img = icon.getImage(); + newimg = img.getScaledInstance(iconSize, iconSize, java.awt.Image.SCALE_SMOOTH); + btnNewTable.setIcon(new ImageIcon(newimg)); + + icon = new javax.swing.ImageIcon(getClass().getResource("/buttons/tourney_new.png")); + img = icon.getImage(); + newimg = img.getScaledInstance(iconSize, iconSize, java.awt.Image.SCALE_SMOOTH); + btnNewTournament.setIcon(new ImageIcon(newimg)); + + for (JToggleButton component : filterButtons) { + component.setFont(GUISizeHelper.menuFont); + } + Dimension newDimension = new Dimension((int) jPanelBottom.getPreferredSize().getWidth(), GUISizeHelper.menuFont.getSize() + 28); + jPanelBottom.setMinimumSize(newDimension); + jPanelBottom.setPreferredSize(newDimension); + jButtonFooterNext.setFont(GUISizeHelper.menuFont); + jLabelFooterLabel.setFont(new Font(GUISizeHelper.menuFont.getName(), Font.BOLD, GUISizeHelper.menuFont.getSize())); + jLabelFooterText.setFont(GUISizeHelper.menuFont); + } + + private void saveDividerLocations() { + // save divider locations and divider saveDividerLocations + GuiDisplayUtil.saveCurrentBoundsToPrefs(); + GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_1, this.jSplitPane1.getDividerLocation()); + GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_2, this.jSplitPaneTables.getDividerLocation()); + GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_3, chatPanelMain.getSplitDividerLocation()); + } + + private void restoreFilters() { + TableUtil.setActiveFilters(KEY_TABLES_FILTER_SETTINGS, filterButtons); + setTableFilter(); + } + + private void saveGuiSettings() { + TableUtil.saveActiveFiltersToPrefs(KEY_TABLES_FILTER_SETTINGS, filterButtons); + TableUtil.saveColumnWidthAndOrderToPrefs(tableTables, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER); + } + + private void restoreDividers() { + Rectangle currentBounds = MageFrame.getDesktop().getBounds(); + if (currentBounds != null) { + String firstDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_1, null); + String tableDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_2, null); + String chatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_3, null); + GuiDisplayUtil.restoreDividerLocations(currentBounds, firstDivider, jSplitPane1); + GuiDisplayUtil.restoreDividerLocations(currentBounds, tableDivider, jSplitPaneTables); + GuiDisplayUtil.restoreDividerLocations(currentBounds, chatDivider, chatPanelMain); + } + } + + public Map getUIComponents() { + Map components = new HashMap<>(); + + components.put("jScrollPane1", jScrollPaneTablesActive); + components.put("jScrollPane1ViewPort", jScrollPaneTablesActive.getViewport()); + components.put("jPanel1", jPanelTop); + components.put("tablesPanel", this); + + return components; + } + + public void updateTables(Collection tables) { + try { + tableModel.loadData(tables); + this.tableTables.repaint(); + } catch (MageRemoteException ex) { + hideTables(); + } + } + + public void updateMatches(Collection matches) { + try { + matchesModel.loadData(matches); + this.tableCompleted.repaint(); + } catch (MageRemoteException ex) { + hideTables(); + } + } + + public void startTasks() { + if (SessionHandler.getSession() != null) { + if (updateTablesTask == null || updateTablesTask.isDone()) { + updateTablesTask = new UpdateTablesTask(roomId, this); + updateTablesTask.execute(); + } + if (updatePlayersTask == null || updatePlayersTask.isDone()) { + updatePlayersTask = new UpdatePlayersTask(roomId, this.chatPanelMain); + updatePlayersTask.execute(); + } + if (this.btnStateFinished.isSelected()) { + if (updateMatchesTask == null || updateMatchesTask.isDone()) { + updateMatchesTask = new UpdateMatchesTask(roomId, this); + updateMatchesTask.execute(); + } + } else if (updateMatchesTask != null) { + updateMatchesTask.cancel(true); + } + } + } + + public void stopTasks() { + if (updateTablesTask != null) { + updateTablesTask.cancel(true); + } + if (updatePlayersTask != null) { + updatePlayersTask.cancel(true); + } + if (updateMatchesTask != null) { + updateMatchesTask.cancel(true); + } + } + + public void showTables(UUID roomId) { + this.roomId = roomId; + UUID chatRoomId = null; + if (SessionHandler.getSession() != null) { + btnQuickStart.setVisible(SessionHandler.isTestMode()); + gameChooser.init(); + chatRoomId = SessionHandler.getRoomChatId(roomId).orElse(null); + } + if (newTableDialog == null) { + newTableDialog = new NewTableDialog(); + MageFrame.getDesktop().add(newTableDialog, JLayeredPane.MODAL_LAYER); + } + if (newTournamentDialog == null) { + newTournamentDialog = new NewTournamentDialog(); + MageFrame.getDesktop().add(newTournamentDialog, JLayeredPane.MODAL_LAYER); + } + if (joinTableDialog == null) { + joinTableDialog = new JoinTableDialog(); + MageFrame.getDesktop().add(joinTableDialog, JLayeredPane.MODAL_LAYER); + } + if (chatRoomId != null) { + this.chatPanelMain.getUserChatPanel().connect(chatRoomId); + startTasks(); + this.setVisible(true); + this.repaint(); + } else { + hideTables(); + } + //tableModel.setSession(session); + + reloadMessages(); + + MageFrame.getUI().addButton(MageComponents.NEW_GAME_BUTTON, btnNewTable); + + // divider locations have to be set with delay else values set are overwritten with system defaults + Executors.newSingleThreadScheduledExecutor().schedule(() -> restoreDividers(), 300, TimeUnit.MILLISECONDS); + + } + + protected void reloadMessages() { + // reload server messages + java.util.List serverMessages = SessionHandler.getServerMessages(); + synchronized (this) { + this.messages = serverMessages; + this.currentMessage = 0; + } + if (serverMessages.isEmpty()) { + this.jPanelBottom.setVisible(false); + } else { + this.jPanelBottom.setVisible(true); + URLHandler.RemoveMouseAdapter(jLabelFooterText); + URLHandler.handleMessage(serverMessages.get(0), this.jLabelFooterText); + this.jButtonFooterNext.setVisible(serverMessages.size() > 1); + } + } + + public void hideTables() { + this.saveDividerLocations(); + for (Component component : MageFrame.getDesktop().getComponents()) { + if (component instanceof TableWaitingDialog) { + ((TableWaitingDialog) component).closeDialog(); + } + } + stopTasks(); + this.chatPanelMain.getUserChatPanel().disconnect(); + + Component c = this.getParent(); + while (c != null && !(c instanceof TablesPane)) { + c = c.getParent(); + } + if (c != null) { + ((TablesPane) c).hideFrame(); + } + } + + public ChatPanelBasic getChatPanel() { + return chatPanelMain.getUserChatPanel(); + } + + public void setTableFilter() { + // state + java.util.List> stateFilterList = new ArrayList<>(); + if (btnStateWaiting.isSelected()) { + stateFilterList.add(RowFilter.regexFilter("Waiting", TableTableModel.COLUMN_STATUS)); + } + if (btnStateActive.isSelected()) { + stateFilterList.add(RowFilter.regexFilter("Dueling|Constructing|Drafting|Sideboard", TableTableModel.COLUMN_STATUS)); + } + + // type + java.util.List> typeFilterList = new ArrayList<>(); + if (btnTypeMatch.isSelected()) { + typeFilterList.add(RowFilter.regexFilter("Two|Commander|Free|Tiny|Momir", TableTableModel.COLUMN_GAME_TYPE)); + } + if (btnTypeTourneyConstructed.isSelected()) { + typeFilterList.add(RowFilter.regexFilter("Constructed", TableTableModel.COLUMN_GAME_TYPE)); + } + if (btnTypeTourneyLimited.isSelected()) { + typeFilterList.add(RowFilter.regexFilter("Booster|Sealed", TableTableModel.COLUMN_GAME_TYPE)); + } + + // format + java.util.List> formatFilterList = new ArrayList<>(); + if (btnFormatBlock.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Constructed.*Block", TableTableModel.COLUMN_DECK_TYPE)); + } + if (btnFormatStandard.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Constructed - Standard", TableTableModel.COLUMN_DECK_TYPE)); + } + if (btnFormatModern.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Constructed - Modern", TableTableModel.COLUMN_DECK_TYPE)); + } + if (btnFormatLegacy.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Constructed - Legacy", TableTableModel.COLUMN_DECK_TYPE)); + } + if (btnFormatVintage.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Constructed - Vintage", TableTableModel.COLUMN_DECK_TYPE)); + } + if (btnFormatCommander.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander|^Penny Dreadful Commander|^Freeform Commander|^MTGO 1v1 Commander|^Duel Brawl|^Brawl", TableTableModel.COLUMN_DECK_TYPE)); + } + if (btnFormatTinyLeader.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Tiny", TableTableModel.COLUMN_DECK_TYPE)); + } + if (btnFormatLimited.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Limited", TableTableModel.COLUMN_DECK_TYPE)); + } + if (btnFormatOther.isSelected()) { + formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander|^Canadian Highlander|^Constructed - Old", TableTableModel.COLUMN_DECK_TYPE)); + } + + // skill + java.util.List> skillFilterList = new ArrayList<>(); + if (btnSkillBeginner.isSelected()) { + skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.BEGINNER, true), TableTableModel.COLUMN_SKILL)); + } + if (btnSkillCasual.isSelected()) { + skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.CASUAL, true), TableTableModel.COLUMN_SKILL)); + } + if (btnSkillSerious.isSelected()) { + skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.SERIOUS, true), TableTableModel.COLUMN_SKILL)); + } + + String ratedMark = TableTableModel.RATED_VALUE_YES; + java.util.List> ratingFilterList = new ArrayList<>(); + if (btnRated.isSelected()) { + // yes word + ratingFilterList.add(RowFilter.regexFilter("^" + ratedMark, TableTableModel.COLUMN_RATING)); + } + if (btnUnrated.isSelected()) { + // not yes word, see https://stackoverflow.com/a/406408/1276632 + ratingFilterList.add(RowFilter.regexFilter("^((?!" + ratedMark + ").)*$", TableTableModel.COLUMN_RATING)); + } + + // Password + String passwordMark = TableTableModel.PASSWORD_VALUE_YES; + java.util.List> passwordFilterList = new ArrayList<>(); + if (btnPassword.isSelected()) { + // yes + passwordFilterList.add(RowFilter.regexFilter("^" + passwordMark, TableTableModel.COLUMN_PASSWORD)); + } + if (btnOpen.isSelected()) { + // no + passwordFilterList.add(RowFilter.regexFilter("^((?!" + passwordMark + ").)*$", TableTableModel.COLUMN_PASSWORD)); + } + + // Hide games of ignored players + java.util.List> ignoreListFilterList = new ArrayList<>(); + String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); + final Set ignoreListCopy = IgnoreList.ignoreList(serverAddress); + if (!ignoreListCopy.isEmpty()) { + ignoreListFilterList.add(new RowFilter() { + @Override + public boolean include(Entry entry) { + final String owner = entry.getStringValue(TableTableModel.COLUMN_OWNER); + return !ignoreListCopy.contains(owner); + } + }); + } + + if (stateFilterList.isEmpty() || typeFilterList.isEmpty() || formatFilterList.isEmpty() + || skillFilterList.isEmpty() || ratingFilterList.isEmpty() + || passwordFilterList.isEmpty()) { // no selection + activeTablesSorter.setRowFilter(RowFilter.regexFilter("Nothing", TableTableModel.COLUMN_SKILL)); + } else { + java.util.List> filterList = new ArrayList<>(); + + if (stateFilterList.size() > 1) { + filterList.add(RowFilter.orFilter(stateFilterList)); + } else if (stateFilterList.size() == 1) { + filterList.addAll(stateFilterList); + } + + if (typeFilterList.size() > 1) { + filterList.add(RowFilter.orFilter(typeFilterList)); + } else if (typeFilterList.size() == 1) { + filterList.addAll(typeFilterList); + } + + if (formatFilterList.size() > 1) { + filterList.add(RowFilter.orFilter(formatFilterList)); + } else if (formatFilterList.size() == 1) { + filterList.addAll(formatFilterList); + } + + if (skillFilterList.size() > 1) { + filterList.add(RowFilter.orFilter(skillFilterList)); + } else if (skillFilterList.size() == 1) { + filterList.addAll(skillFilterList); + } + + if (ratingFilterList.size() > 1) { + filterList.add(RowFilter.orFilter(ratingFilterList)); + } else if (ratingFilterList.size() == 1) { + filterList.addAll(ratingFilterList); + } + + if (passwordFilterList.size() > 1) { + filterList.add(RowFilter.orFilter(passwordFilterList)); + } else if (passwordFilterList.size() == 1) { + filterList.addAll(passwordFilterList); + } + + if (ignoreListFilterList.size() > 1) { + filterList.add(RowFilter.orFilter(ignoreListFilterList)); + } else if (ignoreListFilterList.size() == 1) { + filterList.addAll(ignoreListFilterList); + } + + if (filterList.size() == 1) { + activeTablesSorter.setRowFilter(filterList.get(0)); + } else { + activeTablesSorter.setRowFilter(RowFilter.andFilter(filterList)); + } + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jPanelTop = new javax.swing.JPanel(); + btnNewTable = new javax.swing.JButton(); + btnNewTournament = new javax.swing.JButton(); + filterBar1 = new javax.swing.JToolBar(); + btnStateWaiting = new javax.swing.JToggleButton(); + btnStateActive = new javax.swing.JToggleButton(); + btnStateFinished = new javax.swing.JToggleButton(); + jSeparator1 = new javax.swing.JToolBar.Separator(); + btnTypeMatch = new javax.swing.JToggleButton(); + btnTypeTourneyConstructed = new javax.swing.JToggleButton(); + btnTypeTourneyLimited = new javax.swing.JToggleButton(); + jSeparator4 = new javax.swing.JToolBar.Separator(); + btnSkillBeginner = new javax.swing.JToggleButton(); + btnSkillCasual = new javax.swing.JToggleButton(); + btnSkillSerious = new javax.swing.JToggleButton(); + jSeparator5 = new javax.swing.JToolBar.Separator(); + btnRated = new javax.swing.JToggleButton(); + btnUnrated = new javax.swing.JToggleButton(); + filterBar2 = new javax.swing.JToolBar(); + btnFormatBlock = new javax.swing.JToggleButton(); + btnFormatStandard = new javax.swing.JToggleButton(); + btnFormatModern = new javax.swing.JToggleButton(); + btnFormatLegacy = new javax.swing.JToggleButton(); + btnFormatVintage = new javax.swing.JToggleButton(); + jSeparator3 = new javax.swing.JToolBar.Separator(); + btnFormatCommander = new javax.swing.JToggleButton(); + btnFormatTinyLeader = new javax.swing.JToggleButton(); + jSeparator2 = new javax.swing.JToolBar.Separator(); + btnFormatLimited = new javax.swing.JToggleButton(); + btnFormatOther = new javax.swing.JToggleButton(); + jSeparator5 = new javax.swing.JToolBar.Separator(); + btnOpen = new javax.swing.JToggleButton(); + btnPassword = new javax.swing.JToggleButton(); + btnQuickStart = new javax.swing.JButton(); + jSplitPane1 = new javax.swing.JSplitPane(); + jPanelTables = new javax.swing.JPanel(); + jSplitPaneTables = new javax.swing.JSplitPane(); + jScrollPaneTablesActive = new javax.swing.JScrollPane(); + tableTables = new javax.swing.JTable(); + jScrollPaneTablesFinished = new javax.swing.JScrollPane(); + tableCompleted = new javax.swing.JTable(); + chatPanelMain = new mage.client.table.PlayersChatPanel(); + jPanelBottom = new javax.swing.JPanel(); + jButtonFooterNext = new javax.swing.JButton(); + jLabelFooterLabel = new javax.swing.JLabel(); + jLabelFooterText = new javax.swing.JLabel(); + + setLayout(new java.awt.GridBagLayout()); + + jPanelTop.setBackground(java.awt.Color.white); + jPanelTop.setOpaque(false); + + btnNewTable.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/match_new.png"))); // NOI18N + btnNewTable.setToolTipText("Creates a new match table."); + btnNewTable.setMargin(new java.awt.Insets(2, 2, 2, 2)); + btnNewTable.addActionListener(evt -> btnNewTableActionPerformed(evt)); + + btnNewTournament.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/tourney_new.png"))); // NOI18N + btnNewTournament.setToolTipText("Creates a new tourney table."); + btnNewTournament.setMargin(new java.awt.Insets(2, 2, 2, 2)); + btnNewTournament.addActionListener(evt -> btnNewTournamentActionPerformed(evt)); + + filterBar1.setFloatable(false); + filterBar1.setForeground(new java.awt.Color(102, 102, 255)); + filterBar1.setFocusable(false); + filterBar1.setOpaque(false); + + btnStateWaiting.setSelected(true); + btnStateWaiting.setToolTipText("Shows all tables waiting for players."); + btnStateWaiting.setActionCommand("stateWait"); + btnStateWaiting.setFocusPainted(false); + btnStateWaiting.setFocusable(false); + btnStateWaiting.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnStateWaiting.setRequestFocusEnabled(false); + btnStateWaiting.setVerifyInputWhenFocusTarget(false); + btnStateWaiting.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnStateWaiting.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnStateWaiting); + + btnStateActive.setSelected(true); + btnStateActive.setToolTipText("Shows all tables with active matches."); + btnStateActive.setActionCommand("stateActive"); + btnStateActive.setFocusPainted(false); + btnStateActive.setFocusable(false); + btnStateActive.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnStateActive.setRequestFocusEnabled(false); + btnStateActive.setVerifyInputWhenFocusTarget(false); + btnStateActive.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnStateActive.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnStateActive); + + btnStateFinished.setSelected(true); + btnStateFinished.setToolTipText("Toggles the visibility of the table of completed
matches and tournaments in the lower area.\n
Showing the last 50 finished matches."); + btnStateFinished.setActionCommand("stateFinished"); + btnStateFinished.setFocusPainted(false); + btnStateFinished.setFocusable(false); + btnStateFinished.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnStateFinished.setRequestFocusEnabled(false); + btnStateFinished.setVerifyInputWhenFocusTarget(false); + btnStateFinished.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnStateFinished.addActionListener(evt -> btnStateFinishedActionPerformed(evt)); + filterBar1.add(btnStateFinished); + filterBar1.add(jSeparator1); + + btnTypeMatch.setSelected(true); + btnTypeMatch.setText("Matches"); + btnTypeMatch.setToolTipText("Shows all non tournament tables."); + btnTypeMatch.setActionCommand("typeMatch"); + btnTypeMatch.setFocusPainted(false); + btnTypeMatch.setFocusable(false); + btnTypeMatch.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnTypeMatch.setRequestFocusEnabled(false); + btnTypeMatch.setVerifyInputWhenFocusTarget(false); + btnTypeMatch.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnTypeMatch.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnTypeMatch); + + btnTypeTourneyConstructed.setSelected(true); + btnTypeTourneyConstructed.setText("Constructed tourn."); + btnTypeTourneyConstructed.setToolTipText("Shows all constructed tournament tables."); + btnTypeTourneyConstructed.setActionCommand("typeTourneyConstructed"); + btnTypeTourneyConstructed.setFocusPainted(false); + btnTypeTourneyConstructed.setFocusable(false); + btnTypeTourneyConstructed.setRequestFocusEnabled(false); + btnTypeTourneyConstructed.setVerifyInputWhenFocusTarget(false); + btnTypeTourneyConstructed.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnTypeTourneyConstructed); + + btnTypeTourneyLimited.setSelected(true); + btnTypeTourneyLimited.setText("Limited tourn."); + btnTypeTourneyLimited.setToolTipText("Shows all limited tournament tables."); + btnTypeTourneyLimited.setActionCommand("typeTourneyLimited"); + btnTypeTourneyLimited.setFocusPainted(false); + btnTypeTourneyLimited.setFocusable(false); + btnTypeTourneyLimited.setMaximumSize(new java.awt.Dimension(72, 20)); + btnTypeTourneyLimited.setRequestFocusEnabled(false); + btnTypeTourneyLimited.setVerifyInputWhenFocusTarget(false); + btnTypeTourneyLimited.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnTypeTourneyLimited); + filterBar1.add(jSeparator4); + + btnSkillBeginner.setSelected(true); + btnSkillBeginner.setText("Beginner"); + btnSkillBeginner.setToolTipText("Shows all tables with skill level beginner."); + btnSkillBeginner.setActionCommand("typeMatch"); + btnSkillBeginner.setFocusPainted(false); + btnSkillBeginner.setFocusable(false); + btnSkillBeginner.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnSkillBeginner.setRequestFocusEnabled(false); + btnSkillBeginner.setVerifyInputWhenFocusTarget(false); + btnSkillBeginner.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnSkillBeginner.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnSkillBeginner); + + btnSkillCasual.setSelected(true); + btnSkillCasual.setText("Casual"); + btnSkillCasual.setToolTipText("Shows all tables with skill level casual."); + btnSkillCasual.setActionCommand("typeMatch"); + btnSkillCasual.setFocusPainted(false); + btnSkillCasual.setFocusable(false); + btnSkillCasual.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnSkillCasual.setRequestFocusEnabled(false); + btnSkillCasual.setVerifyInputWhenFocusTarget(false); + btnSkillCasual.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnSkillCasual.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnSkillCasual); + + btnSkillSerious.setSelected(true); + btnSkillSerious.setText("Serious"); + btnSkillSerious.setToolTipText("Shows all tables with skill level serious."); + btnSkillSerious.setActionCommand("typeMatch"); + btnSkillSerious.setFocusPainted(false); + btnSkillSerious.setFocusable(false); + btnSkillSerious.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnSkillSerious.setRequestFocusEnabled(false); + btnSkillSerious.setVerifyInputWhenFocusTarget(false); + btnSkillSerious.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnSkillSerious.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnSkillSerious); + + filterBar1.add(jSeparator4); + + btnRated.setSelected(true); + btnRated.setText("Rated"); + btnRated.setToolTipText("Shows all rated tables."); + btnRated.setFocusPainted(false); + btnRated.setFocusable(false); + btnRated.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnRated.setRequestFocusEnabled(false); + btnRated.setVerifyInputWhenFocusTarget(false); + btnRated.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnRated.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnRated); + + btnUnrated.setSelected(true); + btnUnrated.setText("Unrated"); + btnUnrated.setToolTipText("Shows all unrated tables."); + btnUnrated.setFocusPainted(false); + btnUnrated.setFocusable(false); + btnUnrated.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnUnrated.setRequestFocusEnabled(false); + btnUnrated.setVerifyInputWhenFocusTarget(false); + btnUnrated.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnUnrated.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar1.add(btnUnrated); + + // second filter line + filterBar2.setFloatable(false); + filterBar2.setFocusable(false); + filterBar2.setOpaque(false); + + btnFormatBlock.setSelected(true); + btnFormatBlock.setText("Block"); + btnFormatBlock.setToolTipText("Block constructed formats."); + btnFormatBlock.setFocusPainted(false); + btnFormatBlock.setFocusable(false); + btnFormatBlock.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnFormatBlock.setRequestFocusEnabled(false); + btnFormatBlock.setVerifyInputWhenFocusTarget(false); + btnFormatBlock.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnFormatBlock.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatBlock); + + btnFormatStandard.setSelected(true); + btnFormatStandard.setText("Standard"); + btnFormatStandard.setToolTipText("Standard format."); + btnFormatStandard.setFocusPainted(false); + btnFormatStandard.setFocusable(false); + btnFormatStandard.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnFormatStandard.setRequestFocusEnabled(false); + btnFormatStandard.setVerifyInputWhenFocusTarget(false); + btnFormatStandard.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnFormatStandard.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatStandard); + + btnFormatModern.setSelected(true); + btnFormatModern.setText("Modern"); + btnFormatModern.setToolTipText("Modern format."); + btnFormatModern.setFocusPainted(false); + btnFormatModern.setFocusable(false); + btnFormatModern.setRequestFocusEnabled(false); + btnFormatModern.setVerifyInputWhenFocusTarget(false); + btnFormatModern.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatModern); + + btnFormatLegacy.setSelected(true); + btnFormatLegacy.setText("Legacy"); + btnFormatLegacy.setToolTipText("Legacy format."); + btnFormatLegacy.setFocusPainted(false); + btnFormatLegacy.setFocusable(false); + btnFormatLegacy.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnFormatLegacy.setRequestFocusEnabled(false); + btnFormatLegacy.setVerifyInputWhenFocusTarget(false); + btnFormatLegacy.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnFormatLegacy.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatLegacy); + + btnFormatVintage.setSelected(true); + btnFormatVintage.setText("Vintage"); + btnFormatVintage.setToolTipText("Vintage format."); + btnFormatVintage.setFocusPainted(false); + btnFormatVintage.setFocusable(false); + btnFormatVintage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnFormatVintage.setRequestFocusEnabled(false); + btnFormatVintage.setVerifyInputWhenFocusTarget(false); + btnFormatVintage.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnFormatVintage.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatVintage); + filterBar2.add(jSeparator3); + + btnFormatCommander.setSelected(true); + btnFormatCommander.setText("Commander"); + btnFormatCommander.setToolTipText("Commander format."); + btnFormatCommander.setFocusPainted(false); + btnFormatCommander.setFocusable(false); + btnFormatCommander.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnFormatCommander.setRequestFocusEnabled(false); + btnFormatCommander.setVerifyInputWhenFocusTarget(false); + btnFormatCommander.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnFormatCommander.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatCommander); + + btnFormatTinyLeader.setSelected(true); + btnFormatTinyLeader.setText("Tiny Leader"); + btnFormatTinyLeader.setToolTipText("Tiny Leader format."); + btnFormatTinyLeader.setFocusPainted(false); + btnFormatTinyLeader.setFocusable(false); + btnFormatTinyLeader.setRequestFocusEnabled(false); + btnFormatTinyLeader.setVerifyInputWhenFocusTarget(false); + btnFormatTinyLeader.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatTinyLeader); + filterBar2.add(jSeparator2); + + btnFormatLimited.setSelected(true); + btnFormatLimited.setText("Limited"); + btnFormatLimited.setToolTipText("Limited format."); + btnFormatLimited.setFocusPainted(false); + btnFormatLimited.setFocusable(false); + btnFormatLimited.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnFormatLimited.setRequestFocusEnabled(false); + btnFormatLimited.setVerifyInputWhenFocusTarget(false); + btnFormatLimited.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnFormatLimited.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatLimited); + + btnFormatOther.setSelected(true); + btnFormatOther.setText("Other"); + btnFormatOther.setToolTipText("Other formats (Freeform, Pauper, Extended, etc.)"); + btnFormatOther.setFocusPainted(false); + btnFormatOther.setFocusable(false); + btnFormatOther.setRequestFocusEnabled(false); + btnFormatOther.setVerifyInputWhenFocusTarget(false); + btnFormatOther.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnFormatOther); + filterBar2.add(jSeparator5); + + btnOpen.setSelected(true); + btnOpen.setText("Open"); + btnOpen.setToolTipText("Show open games"); + btnOpen.setFocusPainted(false); + btnOpen.setFocusable(false); + btnOpen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnOpen.setRequestFocusEnabled(false); + btnOpen.setVerifyInputWhenFocusTarget(false); + btnOpen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnOpen.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnOpen); + + btnPassword.setSelected(true); + btnPassword.setText("PW"); + btnPassword.setToolTipText("Show passworded games"); + btnPassword.setFocusPainted(false); + btnPassword.setFocusable(false); + btnPassword.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnPassword.setRequestFocusEnabled(false); + btnPassword.setVerifyInputWhenFocusTarget(false); + btnPassword.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnPassword.addActionListener(evt -> btnFilterActionPerformed(evt)); + filterBar2.add(btnPassword); + + btnQuickStart.setText("Quick Start"); + btnQuickStart.setFocusable(false); + btnQuickStart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnQuickStart.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnQuickStart.addActionListener(evt -> btnQuickStartActionPerformed(evt)); + + javax.swing.GroupLayout jPanelTopLayout = new javax.swing.GroupLayout(jPanelTop); + jPanelTop.setLayout(jPanelTopLayout); + jPanelTopLayout.setHorizontalGroup( + jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelTopLayout.createSequentialGroup() + .addContainerGap() + .addComponent(btnNewTable) + .addGap(6, 6, 6) + .addComponent(btnNewTournament) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 491, Short.MAX_VALUE) + .addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnQuickStart) + .addContainerGap(835, Short.MAX_VALUE)) + ); + jPanelTopLayout.setVerticalGroup( + jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelTopLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnNewTable) + .addComponent(btnNewTournament)) + .addGroup(jPanelTopLayout.createSequentialGroup() + .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnQuickStart)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap()) + ); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + add(jPanelTop, gridBagConstraints); + + jSplitPane1.setBorder(null); + jSplitPane1.setDividerSize(10); + jSplitPane1.setResizeWeight(1.0); + + jSplitPaneTables.setBorder(null); + jSplitPaneTables.setDividerSize(10); + jSplitPaneTables.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + jSplitPaneTables.setResizeWeight(0.5); + + jScrollPaneTablesActive.setBorder(null); + jScrollPaneTablesActive.setViewportBorder(null); + + tableTables.setModel(this.tableModel); + jScrollPaneTablesActive.setViewportView(tableTables); + + jSplitPaneTables.setLeftComponent(jScrollPaneTablesActive); + + jScrollPaneTablesFinished.setBorder(null); + jScrollPaneTablesFinished.setViewportBorder(null); + jScrollPaneTablesFinished.setMinimumSize(new java.awt.Dimension(23, 0)); + + tableCompleted.setModel(this.matchesModel); + jScrollPaneTablesFinished.setViewportView(tableCompleted); + + jSplitPaneTables.setRightComponent(jScrollPaneTablesFinished); + + javax.swing.GroupLayout jPanelTablesLayout = new javax.swing.GroupLayout(jPanelTables); + jPanelTables.setLayout(jPanelTablesLayout); + jPanelTablesLayout.setHorizontalGroup( + jPanelTablesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSplitPaneTables, javax.swing.GroupLayout.PREFERRED_SIZE, 23, Short.MAX_VALUE) + ); + jPanelTablesLayout.setVerticalGroup( + jPanelTablesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSplitPaneTables, javax.swing.GroupLayout.DEFAULT_SIZE, 672, Short.MAX_VALUE) + ); + + jSplitPane1.setLeftComponent(jPanelTables); + jSplitPane1.setRightComponent(chatPanelMain); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(jSplitPane1, gridBagConstraints); + + jPanelBottom.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); + jPanelBottom.setPreferredSize(new java.awt.Dimension(516, 37)); + jPanelBottom.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); + + jButtonFooterNext.setText("Next"); + jButtonFooterNext.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jButtonFooterNext.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + jButtonFooterNext.setOpaque(false); + jButtonFooterNext.addActionListener(evt -> jButtonFooterNextActionPerformed(evt)); + jPanelBottom.add(jButtonFooterNext); + + jLabelFooterLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N + jLabelFooterLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabelFooterLabel.setText("Message of the Day:"); + jLabelFooterLabel.setAlignmentY(0.3F); + jPanelBottom.add(jLabelFooterLabel); + + jLabelFooterText.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jLabelFooterText.setText("You are playing Mage version 0.7.5. Welcome! -- Mage dev team --"); + jPanelBottom.add(jLabelFooterText); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + add(jPanelBottom, gridBagConstraints); + }//
//GEN-END:initComponents + + private void btnNewTournamentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTournamentActionPerformed + newTournamentDialog.showDialog(roomId); + }//GEN-LAST:event_btnNewTournamentActionPerformed + + private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed + TableView table; + try { + File f = new File("test.dck"); + if (!f.exists()) { + JOptionPane.showMessageDialog(null, "Couldn't find test.dck file for quick game start", "Error", JOptionPane.ERROR_MESSAGE); + return; + } + + MatchOptions options = new MatchOptions("1", "Two Player Duel", false, 2); + options.getPlayerTypes().add(PlayerType.HUMAN); + options.getPlayerTypes().add(PlayerType.COMPUTER_MAD); + options.setDeckType("Limited"); + options.setAttackOption(MultiplayerAttackOption.LEFT); + options.setRange(RangeOfInfluence.ALL); + options.setWinsNeeded(1); + options.setMatchTimeLimit(MatchTimeLimit.NONE); + options.setFreeMulligans(2); + options.setSkillLevel(SkillLevel.CASUAL); + options.setRollbackTurnsAllowed(true); + options.setQuitRatio(100); + String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); + options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); + table = SessionHandler.createTable(roomId, options); + + SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, DeckImporterUtil.importDeck("test.dck"), ""); + SessionHandler.joinTable(roomId, table.getTableId(), "Computer", PlayerType.COMPUTER_MAD, 5, DeckImporterUtil.importDeck("test.dck"), ""); + SessionHandler.startMatch(roomId, table.getTableId()); + } catch (HeadlessException ex) { + handleError(ex); + } + }//GEN-LAST:event_btnQuickStartActionPerformed + + private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed + newTableDialog.showDialog(roomId); + }//GEN-LAST:event_btnNewTableActionPerformed + + private void jButtonFooterNextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonFooterNextActionPerformed + synchronized (this) { + if (messages != null && !messages.isEmpty()) { + currentMessage++; + if (currentMessage >= messages.size()) { + currentMessage = 0; + } + + URLHandler.RemoveMouseAdapter(jLabelFooterText); + URLHandler.handleMessage(messages.get(currentMessage), this.jLabelFooterText); + } + } + }//GEN-LAST:event_jButtonFooterNextActionPerformed + + private void btnFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFilterActionPerformed + setTableFilter(); + }//GEN-LAST:event_btnFilterActionPerformed + + private void btnStateFinishedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStateFinishedActionPerformed + if (this.btnStateFinished.isSelected()) { + this.jSplitPaneTables.setDividerLocation(-1); + } else { + this.jSplitPaneTables.setDividerLocation(this.jPanelTables.getHeight()); + } + this.startTasks(); + }//GEN-LAST:event_btnStateFinishedActionPerformed + + private void handleError(Exception ex) { + LOGGER.fatal("Error loading deck: ", ex); + JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JToggleButton btnFormatBlock; + private javax.swing.JToggleButton btnFormatCommander; + private javax.swing.JToggleButton btnFormatLegacy; + private javax.swing.JToggleButton btnFormatLimited; + private javax.swing.JToggleButton btnFormatModern; + private javax.swing.JToggleButton btnFormatOther; + private javax.swing.JToggleButton btnFormatStandard; + private javax.swing.JToggleButton btnFormatTinyLeader; + private javax.swing.JToggleButton btnFormatVintage; + private javax.swing.JButton btnNewTable; + private javax.swing.JButton btnNewTournament; + private javax.swing.JToggleButton btnOpen; + private javax.swing.JToggleButton btnPassword; + private javax.swing.JButton btnQuickStart; + private javax.swing.JToggleButton btnSkillBeginner; + private javax.swing.JToggleButton btnSkillCasual; + private javax.swing.JToggleButton btnSkillSerious; + private javax.swing.JToggleButton btnRated; + private javax.swing.JToggleButton btnUnrated; + private javax.swing.JToggleButton btnStateActive; + private javax.swing.JToggleButton btnStateFinished; + private javax.swing.JToggleButton btnStateWaiting; + private javax.swing.JToggleButton btnTypeMatch; + private javax.swing.JToggleButton btnTypeTourneyConstructed; + private javax.swing.JToggleButton btnTypeTourneyLimited; + private mage.client.table.PlayersChatPanel chatPanelMain; + private javax.swing.JToolBar filterBar1; + private javax.swing.JToolBar filterBar2; + private javax.swing.JButton jButtonFooterNext; + private javax.swing.JLabel jLabelFooterLabel; + private javax.swing.JLabel jLabelFooterText; + private javax.swing.JPanel jPanelBottom; + private javax.swing.JPanel jPanelTables; + private javax.swing.JPanel jPanelTop; + private javax.swing.JScrollPane jScrollPaneTablesActive; + private javax.swing.JScrollPane jScrollPaneTablesFinished; + private javax.swing.JToolBar.Separator jSeparator1; + private javax.swing.JToolBar.Separator jSeparator2; + private javax.swing.JToolBar.Separator jSeparator3; + private javax.swing.JToolBar.Separator jSeparator4; + private javax.swing.JToolBar.Separator jSeparator5; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JSplitPane jSplitPaneTables; + private javax.swing.JTable tableCompleted; + private javax.swing.JTable tableTables; + // End of variables declaration//GEN-END:variables + + } + + class TableTableModel extends AbstractTableModel { + + final ImageIcon tourneyIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/tourney_icon.png")); + final ImageIcon matchIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/match_icon.png")); + + public static final int COLUMN_ICON = 0; + public static final int COLUMN_DECK_TYPE = 1; // column the deck type is located (starting with 0) Start string is used to check for Limited + public static final int COLUMN_OWNER = 2; + public static final int COLUMN_GAME_TYPE = 3; + public static final int COLUMN_INFO = 4; + public static final int COLUMN_STATUS = 5; + public static final int COLUMN_PASSWORD = 6; + public static final int COLUMN_CREATED = 7; + public static final int COLUMN_SKILL = 8; + public static final int COLUMN_RATING = 9; + public static final int COLUMN_QUIT_RATIO = 10; + public static final int ACTION_COLUMN = 11; // column the action is located (starting with 0) + + public static final String RATED_VALUE_YES = "YES"; + public static final String RATED_VALUE_NO = ""; + + public static final String PASSWORD_VALUE_YES = "YES"; + + private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rating", "Quit %", "Action"}; + + private TableView[] tables = new TableView[0]; + + TableTableModel() { + } + + public void loadData(Collection tables) throws MageRemoteException { + this.tables = tables.toArray(new TableView[0]); + this.fireTableDataChanged(); + } + + public String getSkillLevelAsCode(SkillLevel skill, boolean asRegExp) { + String res; + switch (skill) { + case BEGINNER: + res = "*"; + break; + case CASUAL: + res = "**"; + break; + case SERIOUS: + res = "***"; + break; + default: + res = ""; + break; + } + + // regexp format for search table rows + if (asRegExp) { + res = String.format("^%s$", res.replace("*", "\\*")); + } + + return res; + } + + @Override + public int getRowCount() { + return tables.length; + } + + @Override + public int getColumnCount() { + return columnNames.length; + } + + @Override + public Object getValueAt(int arg0, int arg1) { + switch (arg1) { + case 0: + return tables[arg0].isTournament() ? tourneyIcon : matchIcon; + case 1: + return tables[arg0].getDeckType(); + case 2: + return tables[arg0].getControllerName(); + case 3: + return tables[arg0].getGameType(); + case 4: + return tables[arg0].getAdditionalInfo(); + case 5: + return tables[arg0].getTableStateText(); + case 6: + return tables[arg0].isPassworded() ? PASSWORD_VALUE_YES : ""; + case 7: + return tables[arg0].getCreateTime(); // use cell render, not format here + case 8: + return this.getSkillLevelAsCode(tables[arg0].getSkillLevel(), false); + case 9: + return tables[arg0].isRated() ? RATED_VALUE_YES : RATED_VALUE_NO; + case 10: + return tables[arg0].getQuitRatio(); + case 11: + switch (tables[arg0].getTableState()) { + + case WAITING: + String owner = tables[arg0].getControllerName(); + if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) { + return ""; + } + return "Join"; + case CONSTRUCTING: + case DRAFTING: + if (tables[arg0].isTournament()) { + return "Show"; + } + case DUELING: + if (tables[arg0].isTournament()) { + return "Show"; + } else { + owner = tables[arg0].getControllerName(); + if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) { + return ""; + } + if (tables[arg0].getSpectatorsAllowed()) { + return "Watch"; + } + return ""; + } + default: + return ""; + } + case 12: + return tables[arg0].isTournament(); + case 13: + if (!tables[arg0].getGames().isEmpty()) { + return tables[arg0].getGames().get(0); + } + return null; + case 14: + return tables[arg0].getTableId(); + } + return ""; + } + + @Override + public String getColumnName(int columnIndex) { + String colName = ""; + + if (columnIndex <= getColumnCount()) { + colName = columnNames[columnIndex]; + } + + return colName; + } + + @Override + public Class getColumnClass(int columnIndex) { + switch (columnIndex) { + case COLUMN_ICON: + return Icon.class; + case COLUMN_SKILL: + return SkillLevel.class; + case COLUMN_CREATED: + return Date.class; + default: + return String.class; + } + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return columnIndex == ACTION_COLUMN; + } + + } + + class UpdateTablesTask extends SwingWorker> { + + private final UUID roomId; + private final TablesPanel panel; + + private static final Logger logger = Logger.getLogger(UpdateTablesTask.class); + + private int count = 0; + + UpdateTablesTask(UUID roomId, TablesPanel panel) { + + this.roomId = roomId; + this.panel = panel; + } + + @Override + protected Void doInBackground() throws Exception { + while (!isCancelled()) { + Collection tables = SessionHandler.getTables(roomId); + if (tables != null) { + this.publish(tables); + } + TimeUnit.SECONDS.sleep(3); + } + return null; + } + + @Override + protected void process(java.util.List> view) { + panel.updateTables(view.get(0)); + count++; + if (count > 60) { + count = 0; + panel.reloadMessages(); + } + } + + @Override + protected void done() { + try { + get(); + } catch (InterruptedException | ExecutionException ex) { + logger.fatal("Update Tables Task error", ex); + } catch (CancellationException ex) { + } + } + + } + + class UpdatePlayersTask extends SwingWorker> { + + private final UUID roomId; + private final PlayersChatPanel chat; + + private static final Logger logger = Logger.getLogger(UpdatePlayersTask.class); + + UpdatePlayersTask(UUID roomId, PlayersChatPanel chat) { + + this.roomId = roomId; + this.chat = chat; + } + + @Override + protected Void doInBackground() throws Exception { + while (!isCancelled()) { + this.publish(SessionHandler.getRoomUsers(roomId)); + TimeUnit.SECONDS.sleep(3); + } + return null; + } + + @Override + protected void process(java.util.List> roomUserInfo) { + chat.setRoomUserInfo(roomUserInfo); + } + + @Override + protected void done() { + try { + get(); + } catch (InterruptedException | ExecutionException ex) { + logger.fatal("Update Players Task error", ex); + } catch (CancellationException ex) { + } + } + + } + + class MatchesTableModel extends AbstractTableModel { + + private final String[] columnNames = new String[]{"Deck Type", "Players", "Game Type", "Rating", "Result", "Duration", "Start Time", "End Time", "Action"}; + public static final int COLUMN_DURATION = 5; + public static final int COLUMN_START = 6; + public static final int COLUMN_END = 7; + public static final int COLUMN_ACTION = 8; // column the action is located (starting with 0) + + private MatchView[] matches = new MatchView[0]; + + public void loadData(Collection matches) throws MageRemoteException { + this.matches = matches.toArray(new MatchView[0]); + this.fireTableDataChanged(); + } + + MatchesTableModel() { + } + + @Override + public int getRowCount() { + return matches.length; + } + + @Override + public int getColumnCount() { + return columnNames.length; + } + + @Override + public Object getValueAt(int arg0, int arg1) { + switch (arg1) { + case 0: + return matches[arg0].getDeckType(); + case 1: + return matches[arg0].getPlayers(); + case 2: + return matches[arg0].getGameType(); + case 3: + return matches[arg0].isRated() ? TableTableModel.RATED_VALUE_YES : TableTableModel.RATED_VALUE_NO; + case 4: + return matches[arg0].getResult(); + case 5: + if (matches[arg0].getEndTime() != null) { + return matches[arg0].getEndTime().getTime() - matches[arg0].getStartTime().getTime() + new Date().getTime(); + } else { + return 0L; + } + case 6: + return matches[arg0].getStartTime(); + case 7: + return matches[arg0].getEndTime(); + case 8: + if (matches[arg0].isTournament()) { + return "Show"; + } else if (matches[arg0].isReplayAvailable()) { + return "Replay"; + } else { + return "None"; + } + case 9: + return matches[arg0].getGames(); + } + return ""; + } + + public java.util.List getListofGames(int row) { + return matches[row].getGames(); + } + + public boolean isTournament(int row) { + return matches[row].isTournament(); + } + + public UUID getMatchId(int row) { + return matches[row].getMatchId(); + } + + public UUID getTableId(int row) { + return matches[row].getTableId(); + } + + @Override + public String getColumnName(int columnIndex) { + String colName = ""; + + if (columnIndex <= getColumnCount()) { + colName = columnNames[columnIndex]; + } + + return colName; + } + + @Override + public Class getColumnClass(int columnIndex) { + switch (columnIndex) { + case COLUMN_DURATION: + return Long.class; + case COLUMN_START: + return Date.class; + case COLUMN_END: + return Date.class; + default: + return String.class; + } + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return columnIndex == COLUMN_ACTION; + } + + } + + class UpdateMatchesTask extends SwingWorker> { + + private final UUID roomId; + private final TablesPanel panel; + + private static final Logger logger = Logger.getLogger(UpdateTablesTask.class); + + UpdateMatchesTask(UUID roomId, TablesPanel panel) { + this.roomId = roomId; + this.panel = panel; + } + + @Override + protected Void doInBackground() throws Exception { + while (!isCancelled()) { + Collection matches = SessionHandler.getFinishedMatches(roomId); + if (!matches.isEmpty()) { + this.publish(matches); + } + TimeUnit.SECONDS.sleep(10); + } + return null; + } + + @Override + protected void process(java.util.List> view) { + panel.updateMatches(view.get(0)); + } + + @Override + protected void done() { + try { + get(); + } catch (InterruptedException | ExecutionException ex) { + logger.fatal("Update Matches Task error", ex); + } catch (CancellationException ex) { + } + } + + } + + class GameChooser extends JPopupMenu { + + public void init() { + + } + + public void show(java.util.List games, Point p) { + if (p == null) { + return; + } + this.removeAll(); + for (UUID gameId : games) { + this.add(new GameChooserAction(gameId, gameId.toString())); + } + this.show(MageFrame.getDesktop(), p.x, p.y); + GuiDisplayUtil.keepComponentInsideScreen(p.x, p.y, this); + } + + private class GameChooserAction extends AbstractAction { + + private final UUID id; + + public GameChooserAction(UUID id, String choice) { + this.id = id; + putValue(Action.NAME, choice); + } + + @Override + public void actionPerformed(ActionEvent e) { + SessionHandler.replayGame(id); + setVisible(false); + } + + } + + } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java index 3702f176cb..f32c08e972 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardRendererUtils.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package org.mage.card.arcane; import java.awt.*; @@ -63,26 +58,26 @@ public final class CardRendererUtils { int plus_b = (int) ((255 - b) / 2); return new Color(r + plus_r, - g + plus_g, - b + plus_b, - alpha); + g + plus_g, + b + plus_b, + alpha); } - + public static Color abitdarker(Color c) { int r = c.getRed(); int g = c.getGreen(); int b = c.getBlue(); int alpha = c.getAlpha(); - int plus_r = (int) (Math.min (255 - r, r) / 2); - int plus_g = (int) (Math.min (255 - g, g) / 2); - int plus_b = (int) (Math.min (255 - b, b) / 2); + int plus_r = (int) (Math.min(255 - r, r) / 2); + int plus_g = (int) (Math.min(255 - g, g) / 2); + int plus_b = (int) (Math.min(255 - b, b) / 2); return new Color(r - plus_r, - g - plus_g, - b - plus_b, - alpha); - } + g - plus_g, + b - plus_b, + alpha); + } // Draw a rounded box with a 2-pixel border // Used on various card parts. @@ -192,4 +187,12 @@ public final class CardRendererUtils { .replaceAll("", "") .replaceAll("", ""); } + + public static Color copyColor(Color color) { + if (color != null) { + return new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + } else { + return null; + } + } } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbolsCellRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbolsCellRenderer.java index 46a0e3f1c2..bd9731ec6a 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbolsCellRenderer.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbolsCellRenderer.java @@ -9,10 +9,13 @@ import java.awt.*; import java.awt.image.BufferedImage; import java.util.StringTokenizer; +/** + * @author JayDi85 + */ public final class ManaSymbolsCellRenderer extends DefaultTableCellRenderer { // base panel to render - private JPanel manaPanel = new JPanel(); + private JPanel renderPanel = new JPanel(); @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, @@ -20,47 +23,47 @@ public final class ManaSymbolsCellRenderer extends DefaultTableCellRenderer { // get table text cell settings DefaultTableCellRenderer baseRenderer = (DefaultTableCellRenderer) table.getDefaultRenderer(String.class); - JLabel baseLabel = (JLabel)baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + JLabel baseComp = (JLabel) baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // apply settings to mana panel from parent - manaPanel.setOpaque(baseLabel.isOpaque()); - manaPanel.setForeground(baseLabel.getForeground()); - manaPanel.setBackground(baseLabel.getBackground()); + renderPanel.setOpaque(baseComp.isOpaque()); + renderPanel.setForeground(CardRendererUtils.copyColor(baseComp.getForeground())); + renderPanel.setBackground(CardRendererUtils.copyColor(baseComp.getBackground())); + renderPanel.setBorder(baseComp.getBorder()); // icons size with margin int symbolWidth = GUISizeHelper.symbolTableSize; int symbolHorizontalMargin = 2; // create each mana symbol as child label - String manaCost = (String)value; - manaPanel.removeAll(); - manaPanel.setLayout(new BoxLayout(manaPanel, BoxLayout.X_AXIS)); - if(manaCost != null){ + String manaCost = (String) value; + renderPanel.removeAll(); + renderPanel.setLayout(new BoxLayout(renderPanel, BoxLayout.X_AXIS)); + if (manaCost != null) { StringTokenizer tok = new StringTokenizer(manaCost, " "); while (tok.hasMoreTokens()) { String symbol = tok.nextToken(); JLabel symbolLabel = new JLabel(); //symbolLabel.setBorder(new LineBorder(new Color(150, 150, 150))); // debug - symbolLabel.setBorder(new EmptyBorder(0, symbolHorizontalMargin,0, 0)); + symbolLabel.setBorder(new EmptyBorder(0, symbolHorizontalMargin, 0, 0)); BufferedImage image = ManaSymbols.getSizedManaSymbol(symbol, symbolWidth); - if (image != null){ + if (image != null) { // icon symbolLabel.setIcon(new ImageIcon(image)); - }else - { + } else { // text symbolLabel.setText("{" + symbol + "}"); - symbolLabel.setOpaque(baseLabel.isOpaque()); - symbolLabel.setForeground(baseLabel.getForeground()); - symbolLabel.setBackground(baseLabel.getBackground()); + symbolLabel.setOpaque(baseComp.isOpaque()); + symbolLabel.setForeground(baseComp.getForeground()); + symbolLabel.setBackground(baseComp.getBackground()); } - manaPanel.add(symbolLabel); + renderPanel.add(symbolLabel); } } - return manaPanel; + return renderPanel; } } diff --git a/Mage.Client/src/main/resources/info/yellow_star_16.png b/Mage.Client/src/main/resources/info/yellow_star_16.png new file mode 100644 index 0000000000000000000000000000000000000000..849916980af0a76d8717cc5bc814aa49ee50db28 GIT binary patch literal 478 zcmV<40U`d0P)5kugscQ51#0b7yuKSVLhU1tt=AV&h^shc(^*sz-|q|8+LwhY7rIWh;VXLqMcPuS+p6={~M^*>&jH7?1lob5NOE5w2UDf^gTk` z!9o2GP~v2Zh9y`!r{=peZ4bRK-v(&45B==1B0zY}qNc|Ar8GC!w_+Hm%eZN!E6ZlB@3PskauiVq9`}3mk#5&_{^l$_@tM=lc2u4M?rnCg4D15@2Ijws UXwz-TT>t<807*qoM6N<$f}&T~`~Uy| literal 0 HcmV?d00001 diff --git a/Mage.Client/src/main/resources/info/yellow_star_24.png b/Mage.Client/src/main/resources/info/yellow_star_24.png new file mode 100644 index 0000000000000000000000000000000000000000..41d21f49db2762b8fd01fe75600c69a438dc97f9 GIT binary patch literal 658 zcmV;D0&V??P)0B4t`CbMJ9sXxh#|ncB0O zIrn|v=YGswAV&EMsTF@AwGzi84l1m^&s<|iXV}phzc_HU>i}h{ySvY91yfxG_{Gcx zIJ&RiaCG11yMc3E1He))w*S8YY^%pj4GoAj8?@R( zT;m(<{M6d0%pW^K#?D!-DF=&l?5Y!W@wNc{v;kGODG(kJRUk4XbT(MEw%*>DGR; zqRo!Ow}s$KqIcxSJt|w1kq}?}+m`tCM>8%a^2=`p03=7gO_Og-H=TJv5NmcP;X4e< z_m0UoK*ML6Jo9}Lzs3FCcPiO{-uGytDq!NVq__0Cp3|z>`jC1^T3n}fD{i_1aM|_b zv&Lp*NTrZ{0*&#QfTyk}ue3I!|76VvzGdr0(UXl1Vj7AKU_^RC0G@*Z!eDFwFvxQ- z+5&3gcp5-Y2Y^Hk!=c+X1W>H^+Ma-bSpsGO1W^KoAmj}J1S0mIQ4l1C98XR-o}3UQ zh5&vM_HxK;hO-()^bvw@x_PHq)$ literal 0 HcmV?d00001 diff --git a/Mage.Client/src/main/resources/info/yellow_star_32.png b/Mage.Client/src/main/resources/info/yellow_star_32.png new file mode 100644 index 0000000000000000000000000000000000000000..029025a9a9ea63b71dbb9ce90827471f3b8109f8 GIT binary patch literal 931 zcmV;U16=%xP)noJ zwGv5qwqG6Tr$}o!(Sw8ks+~9h(vqgPw6sSiY4)ns*A9etkDS>s2T)s`aR12ZezbZ9 zP{mMez0x@@ZtGRm-t~Ge2)`YE9Y?(_V2+j>-wjReIsi^Goi(M7zPYOa!TG`C6qCC$ z0anev=*xpgb`3y^q&M1{L9V!%zYCDqZ{!Z3iV4mSf276a-Yrl!Y|Ni7va%ti&quY< z7gV=*#M_ee>%oCwuX$E1dD4hJqLK__>wXIAsdNY?Aj>Y&NMD1(Em3>~UzB+TKSBI* zxbmAEUtGBZ5Y7&NhNI(Z#{<~d+oEn7xK>zy_8y9`Bndu-FC@J1K(b|Z-D1UHmK})u zx$R1uWN~BYISMC|2clbq6jBMIDxR(Emc)|+kx9BAgkyms#7H|u9hbJbEOIY zT*-^8s7?VlGit`NPD1KnP#Zg7q;<7pxC#16v+2G!@bWLIM*q~t_7zP07OE!!XY*XL zRya_3X>Pf*CUplat2x@iIU`EdJGO8t%N$_u%faqZS+Hs_Yp=kmdk0m{{iKaHJz?eVVD2_002ovPDHLk FV1gZQw15Br literal 0 HcmV?d00001 From b1df464e8fa2777b3bfb956e1e3f88a5bf92ea37 Mon Sep 17 00:00:00 2001 From: John Hitchings Date: Fri, 16 Nov 2018 21:57:25 -0800 Subject: [PATCH 140/167] refactor deck import content to include hints --- .../DeckImportFromClipboardDialog.java | 20 ++++++++++++++++--- .../mage/client/plugins/impl/Plugins.java | 10 +++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java index 6c89063217..4b370eee77 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java @@ -16,6 +16,15 @@ import javax.swing.*; public class DeckImportFromClipboardDialog extends JDialog { + private static final String FORMAT_TEXT = + "// Example:\n" + + "//1 Library of Congress\n" + + "//1 Cryptic Gateway\n" + + "//1 Azami, Lady of Scrolls\n" + + "// NB: This is slow as, and will lock your screen :)\n" + + "\n" + + "// Your current clipboard:\n"; + private JPanel contentPane; private JButton buttonOK; private JButton buttonCancel; @@ -25,6 +34,9 @@ public class DeckImportFromClipboardDialog extends JDialog { public DeckImportFromClipboardDialog() { initComponents(); + + onRefreshClipboard(); + setContentPane(contentPane); setModal(true); getRootPane().setDefaultButton(buttonOK); @@ -42,8 +54,6 @@ public class DeckImportFromClipboardDialog extends JDialog { // Close on "ESC" contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - - getClipboardStringData().ifPresent(content -> txtDeckList.setText(content)); } private Optional getClipboardStringData() { @@ -75,6 +85,10 @@ public class DeckImportFromClipboardDialog extends JDialog { dispose(); } + private void onRefreshClipboard() { + txtDeckList.setText(FORMAT_TEXT + getClipboardStringData().orElse("")); + } + public String getTmpPath() { return tmpPath; } @@ -158,7 +172,7 @@ public class DeckImportFromClipboardDialog extends JDialog { txtDeckList.setMinimumSize(new Dimension(250, 400)); txtDeckList.setPreferredSize(new Dimension(550, 400)); - txtDeckList.setText("// Example:\n//1 Library of Congress\n//1 Cryptic Gateway\n//1 Azami, Lady of Scrolls\n// NB: This is slow as, and will lock your screen :)"); + txtDeckList.setText(FORMAT_TEXT); JScrollPane txtScrollableDeckList = new JScrollPane(txtDeckList); panel3.add(txtScrollableDeckList, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, diff --git a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java index d9f1fef14f..1731b0b656 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java @@ -26,6 +26,8 @@ import mage.view.CardView; import mage.view.PermanentView; import net.xeoh.plugins.base.PluginManager; import net.xeoh.plugins.base.impl.PluginManagerFactory; +import net.xeoh.plugins.base.util.uri.ClassURI; + import org.apache.log4j.Logger; import org.mage.plugins.card.CardPluginImpl; import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; @@ -46,13 +48,15 @@ public enum Plugins implements MagePlugins { @Override public void loadPlugins() { - LOGGER.info("Loading plugins..."); pm = PluginManagerFactory.createPluginManager(); pm.addPluginsFrom(new File(PLUGINS_DIRECTORY + File.separator).toURI()); - this.cardPlugin = new CardPluginImpl(); + pm.addPluginsFrom(new ClassURI(CardPluginImpl.class).toURI()); + pm.addPluginsFrom(new ClassURI(ThemePluginImpl.class).toURI()); + + this.cardPlugin = pm.getPlugin(CardPlugin.class); this.counterPlugin = pm.getPlugin(CounterPlugin.class); - this.themePlugin = new ThemePluginImpl(); + this.themePlugin = pm.getPlugin(ThemePlugin.class); LOGGER.info("Done."); } From 30c373c40b18fc596fc8a244e205cf73366a3070 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 17 Nov 2018 11:43:24 +0400 Subject: [PATCH 141/167] Removed bloated log on non text clipboard data --- .../mage/client/deckeditor/DeckImportFromClipboardDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java index 4b370eee77..32f63c8d18 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckImportFromClipboardDialog.java @@ -60,7 +60,7 @@ public class DeckImportFromClipboardDialog extends JDialog { try { return Optional.of((String)Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor)); } catch (HeadlessException | UnsupportedFlavorException | IOException e) { - e.printStackTrace(); + //e.printStackTrace(); } return Optional.empty(); } From 5ffb6e1fd7bf18dad994f34bfa0635560401aa80 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sun, 18 Nov 2018 04:15:47 +0400 Subject: [PATCH 142/167] * Changed default US server from vaporservermtg.com to mtg.powersofwar.com --- .../src/main/java/mage/client/dialog/ConnectDialog.form | 4 ++-- .../src/main/java/mage/client/dialog/ConnectDialog.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form index 5b74e76cbf..c1ef452cc2 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form @@ -340,8 +340,8 @@ - - + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java index 120c35e2c0..10e188e333 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java @@ -270,8 +270,8 @@ public class ConnectDialog extends MageDialog { }); btnFind3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N - btnFind3.setText("W"); - btnFind3.setToolTipText("Connect to vaporservermtg.com (USA)"); + btnFind3.setText("P"); + btnFind3.setToolTipText("Connect to mtg.powersofwar.com (USA)"); btnFind3.setActionCommand("connectXmageus"); btnFind3.setAlignmentY(0.0F); btnFind3.setMargin(new java.awt.Insets(2, 2, 2, 2)); @@ -688,7 +688,7 @@ public class ConnectDialog extends MageDialog { }//GEN-LAST:event_btnFind2findPublicServerActionPerformed private void connectXmageus(java.awt.event.ActionEvent evt) { - String serverAddress = "vapormtgserver.com"; + String serverAddress = "mtg.powersofwar.com"; this.txtServer.setText(serverAddress); this.txtPort.setText("17171"); // Update userName and password according to the chosen server. From d78d818a667d383058ef5673fa1f4bc334f58d01 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 19 Nov 2018 01:03:05 +0400 Subject: [PATCH 143/167] * Fixed not working deck generation for some settings (#5413); --- .../client/deck/generator/DeckGenerator.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java index 88c94f1711..ab7e7b0774 100644 --- a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java +++ b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java @@ -1,4 +1,3 @@ - package mage.client.deck.generator; import java.util.ArrayList; @@ -7,6 +6,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; + import mage.cards.Card; import mage.cards.decks.Deck; import mage.cards.repository.CardCriteria; @@ -123,9 +123,9 @@ public final class DeckGenerator { * non-creatures, lands (including non-basic). Fixes the deck, adjusting for * size and color of the cards retrieved. * - * @param deckSize how big the deck is to generate. + * @param deckSize how big the deck is to generate. * @param allowedColors which colors are allowed in the deck. - * @param setsToUse which sets to use to retrieve cards for this deck. + * @param setsToUse which sets to use to retrieve cards for this deck. * @return the final deck to use. */ private static Deck generateDeck(int deckSize, List allowedColors, List setsToUse) { @@ -180,9 +180,9 @@ public final class DeckGenerator { * non-creatures are retrieved separately to ensure the deck contains a * reasonable mix of both. * - * @param criteria the criteria to search for in the database. + * @param criteria the criteria to search for in the database. * @param spellCount the number of spells that match the criteria needed in - * the deck. + * the deck. */ private static void generateSpells(CardCriteria criteria, int spellCount) { List cardPool = CardRepository.instance.findCards(criteria); @@ -233,7 +233,7 @@ public final class DeckGenerator { * in this deck. Usually the lands will be well balanced relative to the * color of cards. * - * @param criteria the criteria of the lands to search for in the database. + * @param criteria the criteria of the lands to search for in the database. * @param landsCount the amount of lands required for this deck. * @param basicLands information about the basic lands from the sets used. */ @@ -310,10 +310,10 @@ public final class DeckGenerator { * filled. * * @param landsNeeded how many remaining lands are needed. - * @param percentage the percentage needed for each color in the final deck. - * @param count how many of each color can be produced by non-basic lands. - * @param basicLands list of information about basic lands from the - * database. + * @param percentage the percentage needed for each color in the final deck. + * @param count how many of each color can be produced by non-basic lands. + * @param basicLands list of information about basic lands from the + * database. */ private static void addBasicLands(int landsNeeded, Map percentage, Map count, Map> basicLands) { @@ -360,15 +360,14 @@ public final class DeckGenerator { /** * Return a random basic land of the chosen color. * - * @param color the color the basic land should produce. + * @param color the color the basic land should produce. * @param basicLands list of information about basic lands from the - * database. + * database. * @return a single basic land that produces the color needed. */ private static Card getBasicLand(ColoredManaSymbol color, Map> basicLands) { String landName = DeckGeneratorPool.getBasicLandName(color.toString()); List basicLandsInfo = basicLands.get(landName); - return basicLandsInfo.get(RandomUtil.nextInt(basicLandsInfo.size() - 1)).getMockCard().copy(); + return basicLandsInfo.get(RandomUtil.nextInt(basicLandsInfo.size())).getMockCard().copy(); } - } From 9cb69fbc836a3e7501be9a05c35ffb74504c9c2c Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 19 Nov 2018 01:46:44 +0400 Subject: [PATCH 144/167] * Mind Bomb - Fixed that it can't do damage to players with 0 selected cards; --- Mage.Sets/src/mage/cards/m/MindBomb.java | 37 +++++++----------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MindBomb.java b/Mage.Sets/src/mage/cards/m/MindBomb.java index 56a35ad408..26b0855283 100644 --- a/Mage.Sets/src/mage/cards/m/MindBomb.java +++ b/Mage.Sets/src/mage/cards/m/MindBomb.java @@ -1,17 +1,10 @@ package mage.cards.m; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; +import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; import mage.filter.FilterCard; @@ -20,8 +13,11 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetDiscard; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class MindBomb extends CardImpl { @@ -67,6 +63,7 @@ class MindBombEffect extends OneShotEffect { if (controller != null && sourceObject != null) { Map cardsToDiscard = new HashMap<>(); + // choose for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { @@ -77,6 +74,8 @@ class MindBombEffect extends OneShotEffect { cardsToDiscard.put(playerId, cards); } } + + // discard for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { @@ -91,31 +90,17 @@ class MindBombEffect extends OneShotEffect { } } } + + // damage for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { Cards cardsPlayer = cardsToDiscard.get(playerId); - if (cardsPlayer != null && !cardsPlayer.isEmpty()) { + if (cardsPlayer != null) { player.damage(3 - cardsPlayer.size(), source.getId(), game, false, true); } } } - // reveal the searched lands, put in hands, and shuffle -// for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { -// Player player = game.getPlayer(playerId); -// if (player != null) { -// Cards cardsPlayer = cardsToReveal.get(playerId); -// if (cardsPlayer != null) { -// for (UUID cardId : cardsPlayer) { -// Cards cards = new CardsImpl(game.getCard(cardId)); -// Card card = game.getCard(cardId); -// player.revealCards(sourceObject.getIdName() + " (" + player.getName() + ')', cards, game); -// player.moveCards(card, Zone.HAND, source, game); -// player.shuffleLibrary(source, game); -// } -// } -// } -// } return true; } return false; From f15d8a0da8d4d07839b626d09fda640d2cd80667 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 19 Nov 2018 15:39:05 +0400 Subject: [PATCH 145/167] Code cleanup; --- Mage.Client/serverlist.txt | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 Mage.Client/serverlist.txt diff --git a/Mage.Client/serverlist.txt b/Mage.Client/serverlist.txt deleted file mode 100644 index caecdb8ac0..0000000000 --- a/Mage.Client/serverlist.txt +++ /dev/null @@ -1,6 +0,0 @@ -XMage.de 1 (Europe/Germany) fast :xmage.de:17171 -old xmage.de (Europe/Germany) :185.3.232.200:17171 -XMage Players MTG:xmageplayersmtg.ddns.net:17171 -XMage.tahiti :xmage.tahiti.one:443 -Seedds Server (Asia) :115.29.203.80:17171 -localhost -> connect to your local server (must be started):localhost:17171 From d1c1abb967a19e37876d252880564b9323a9bfd0 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 19 Nov 2018 11:17:14 -0600 Subject: [PATCH 146/167] - Fixed #5433 --- .../src/mage/cards/m/MnemonicBetrayal.java | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MnemonicBetrayal.java b/Mage.Sets/src/mage/cards/m/MnemonicBetrayal.java index 019527dd74..ab23ae3bd3 100644 --- a/Mage.Sets/src/mage/cards/m/MnemonicBetrayal.java +++ b/Mage.Sets/src/mage/cards/m/MnemonicBetrayal.java @@ -10,10 +10,11 @@ import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; - import java.util.HashMap; import java.util.Map; import java.util.UUID; +import mage.abilities.effects.AsThoughManaEffect; +import mage.players.ManaPoolItem; /** * @author TheElk801 @@ -69,17 +70,18 @@ class MnemonicBetrayalExileEffect extends OneShotEffect { } Cards cards = new CardsImpl(); Map cardMap = new HashMap(); - for (UUID playerId : game.getOpponents(source.getControllerId())) { - Player player = game.getPlayer(playerId); - if (player != null) { - cards.addAll(player.getGraveyard()); - } - } - for (Card card : cards.getCards(game)) { + game.getOpponents(source.getControllerId()).stream().map((playerId) -> game.getPlayer(playerId)).filter((player) -> (player != null)).forEachOrdered((player) -> { + cards.addAll(player.getGraveyard()); + }); + cards.getCards(game).stream().map((card) -> { cardMap.put(card.getId(), card.getZoneChangeCounter(game)); + return card; + }).map((card) -> { game.addEffect(new MnemonicBetrayalCastFromExileEffect(card, game), source); + return card; + }).forEachOrdered((card) -> { game.addEffect(new MnemonicBetrayalAnyColorEffect(card, game), source); - } + }); controller.moveCardsToExile(cards.getCards(game), source, game, true, source.getSourceId(), source.getSourceObjectIfItStillExists(game).getName()); game.addDelayedTriggeredAbility(new MnemonicBetrayalDelayedTriggeredAbility(cards, cardMap), source); return true; @@ -125,7 +127,7 @@ class MnemonicBetrayalCastFromExileEffect extends AsThoughEffectImpl { } } -class MnemonicBetrayalAnyColorEffect extends AsThoughEffectImpl { +class MnemonicBetrayalAnyColorEffect extends AsThoughEffectImpl implements AsThoughManaEffect { private final Card card; private final int zoneCounter; @@ -154,13 +156,21 @@ class MnemonicBetrayalAnyColorEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (card.getZoneChangeCounter(game) != zoneCounter) { - this.discard(); - return false; + if (objectId.equals(card.getId()) + && card.getZoneChangeCounter(game) <= zoneCounter + 1 + && affectedControllerId.equals(source.getControllerId())) { + return true; + } else { + if (objectId.equals(card.getId())) { + this.discard(); + } } - return objectId.equals(card.getId()) - && card.getZoneChangeCounter(game) == zoneCounter - && affectedControllerId.equals(source.getControllerId()); + return false; + } + + @Override + public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) { + return mana.getFirstAvailable(); } } @@ -240,12 +250,10 @@ class MnemonicBetrayalReturnEffect extends OneShotEffect { return false; } Cards cardsToReturn = new CardsImpl(); - for (Card card : cards.getCards(game)) { - if (game.getState().getZone(card.getId()) == Zone.EXILED - && card.getZoneChangeCounter(game) == cardMap.getOrDefault(card.getId(), -5) + 1) { - cardsToReturn.add(card); - } - } + cards.getCards(game).stream().filter((card) -> (game.getState().getZone(card.getId()) == Zone.EXILED + && card.getZoneChangeCounter(game) == cardMap.getOrDefault(card.getId(), -5) + 1)).forEachOrdered((card) -> { + cardsToReturn.add(card); + }); return player.moveCards(cardsToReturn, Zone.GRAVEYARD, source, game); } } From 0eedca5283ab9a7ff8de0b7e5a571bc10210db7b Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 19 Nov 2018 15:09:36 -0600 Subject: [PATCH 147/167] - Fixed #5393 --- .../mage/cards/a/AminatouTheFateShifter.java | 22 +++++++++++-------- .../src/mage/cards/t/TheEldestReborn.java | 9 ++++---- .../mage/abilities/common/SagaAbility.java | 4 ++-- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java b/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java index 8067fc0183..23a6897b4b 100644 --- a/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java +++ b/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java @@ -44,7 +44,7 @@ public class AminatouTheFateShifter extends CardImpl { } public AminatouTheFateShifter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{W}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{W}{U}{B}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.AMINATOU); @@ -56,7 +56,7 @@ public class AminatouTheFateShifter extends CardImpl { // -1: Exile another target permanent you own, then return it to the battlefield under your control. ability = new LoyaltyAbility(new ExileTargetForSourceEffect(), -1); - ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect()); + ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect(true)); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); @@ -68,6 +68,7 @@ public class AminatouTheFateShifter extends CardImpl { // Aminatou, the Fateshifter can be your commander. this.addAbility(CanBeYourCommanderAbility.getInstance()); } + public AminatouTheFateShifter(final AminatouTheFateShifter card) { super(card); } @@ -79,6 +80,7 @@ public class AminatouTheFateShifter extends CardImpl { } class AminatouPlusEffect extends OneShotEffect { + public AminatouPlusEffect() { super(Outcome.DrawCard); staticText = "draw a card, then put a card from your hand on top of your library"; @@ -118,10 +120,11 @@ class AminatouPlusEffect extends OneShotEffect { } class AminatouUltimateEffect extends OneShotEffect { - public AminatouUltimateEffect (){ + + public AminatouUltimateEffect() { super(Outcome.Benefit); - staticText = "Choose left or right. Each player gains control of all nonland permanents other than Aminatou," + - " the Fateshifter controlled by the next player in the chosen direction."; + staticText = "Choose left or right. Each player gains control of all nonland permanents other than Aminatou," + + " the Fateshifter controlled by the next player in the chosen direction."; } public AminatouUltimateEffect(final AminatouUltimateEffect effect) { @@ -129,7 +132,9 @@ class AminatouUltimateEffect extends OneShotEffect { } @Override - public AminatouUltimateEffect copy(){return new AminatouUltimateEffect(this);} + public AminatouUltimateEffect copy() { + return new AminatouUltimateEffect(this); + } @Override public boolean apply(Game game, Ability source) { @@ -154,7 +159,7 @@ class AminatouUltimateEffect extends OneShotEffect { return false; } // skip players out of range - if (!game.getState().getPlayersInRange(controller.getId(), game).contains(nextPlayer)){ + if (!game.getState().getPlayersInRange(controller.getId(), game).contains(nextPlayer)) { continue; } // save first next player to check for iteration stop @@ -164,7 +169,7 @@ class AminatouUltimateEffect extends OneShotEffect { FilterNonlandPermanent nextPlayerNonlandPermanentsFilter = new FilterNonlandPermanent(); nextPlayerNonlandPermanentsFilter.add(new ControllerIdPredicate(nextPlayer)); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(nextPlayerNonlandPermanentsFilter, game)) { - if (permanent.getId().equals(source.getSourceId())){ + if (permanent.getId().equals(source.getSourceId())) { continue; } ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame, currentPlayer); @@ -188,4 +193,3 @@ class AminatouUltimateEffect extends OneShotEffect { return nextPlayerId; } } - diff --git a/Mage.Sets/src/mage/cards/t/TheEldestReborn.java b/Mage.Sets/src/mage/cards/t/TheEldestReborn.java index 666e52d657..c8120d042e 100644 --- a/Mage.Sets/src/mage/cards/t/TheEldestReborn.java +++ b/Mage.Sets/src/mage/cards/t/TheEldestReborn.java @@ -1,4 +1,3 @@ - package mage.cards.t; import java.util.UUID; @@ -13,7 +12,6 @@ import mage.constants.SagaChapter; import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.FilterCard; -import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -35,11 +33,12 @@ public final class TheEldestReborn extends CardImpl { } private static final FilterControlledPermanent filterSacrifice = new FilterControlledPermanent("creature or planeswalker"); + static { filterSacrifice.add(Predicates.or( - new CardTypePredicate(CardType.CREATURE), - new CardTypePredicate(CardType.PLANESWALKER) - )); + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.PLANESWALKER) + )); } diff --git a/Mage/src/main/java/mage/abilities/common/SagaAbility.java b/Mage/src/main/java/mage/abilities/common/SagaAbility.java index 954ed8930d..624221c13e 100644 --- a/Mage/src/main/java/mage/abilities/common/SagaAbility.java +++ b/Mage/src/main/java/mage/abilities/common/SagaAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.common; import mage.abilities.Ability; @@ -138,7 +137,8 @@ class ChapterTriggeredAbility extends TriggeredAbilityImpl { if (event.getTargetId().equals(getSourceId()) && event.getData().equals(CounterType.LORE.getName())) { int amountAdded = event.getAmount(); int loreCounters = amountAdded; - Permanent sourceSaga = game.getPermanentOrLKIBattlefield(getSourceId()); + //Permanent sourceSaga = game.getPermanentOrLKIBattlefield(getSourceId()); BUG #5393 + Permanent sourceSaga = game.getPermanent(getSourceId()); if (sourceSaga == null) { sourceSaga = game.getPermanentEntering(getSourceId()); } From 9916dbdad7b59c43e58e71f691267eea619dceaf Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 19 Nov 2018 16:55:46 -0600 Subject: [PATCH 148/167] - Fixed #5434 --- .../src/mage/cards/a/AngelOfSerenity.java | 121 ++---------------- 1 file changed, 14 insertions(+), 107 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java b/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java index b34df8718c..4dfb63bbc4 100644 --- a/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java +++ b/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java @@ -1,43 +1,34 @@ - package mage.cards.a; import java.util.UUID; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; -import mage.abilities.common.ZoneChangeTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.effects.common.ReturnFromExileForSourceEffect; import mage.abilities.keyword.FlyingAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.AnotherPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardIdPredicate; import mage.target.Target; -import mage.target.common.TargetCardInGraveyard; -import mage.target.common.TargetCreaturePermanent; -import mage.util.CardUtil; +import mage.target.common.TargetCardInGraveyardOrBattlefield; /** * * @author LevelX2 */ public final class AngelOfSerenity extends CardImpl { + + private static final String rule = "you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards."; public AngelOfSerenity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}{W}"); this.subtype.add(SubType.ANGEL); this.power = new MageInt(5); @@ -47,7 +38,12 @@ public final class AngelOfSerenity extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Angel of Serenity enters the battlefield, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards. - this.addAbility(new AngelOfSerenityTriggeredAbility()); + FilterCreatureCard filter = new FilterCreatureCard("creatures from the battlefield and/or a graveyard"); + filter.add(Predicates.not(new CardIdPredicate(this.getId()))); + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect().setText(rule), true); + Target target = new TargetCardInGraveyardOrBattlefield(0, 3, filter); + ability.addTarget(target); + this.addAbility(ability); // When Angel of Serenity leaves the battlefield, return the exiled cards to their owners' hands. this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.HAND, false, true), false)); @@ -62,92 +58,3 @@ public final class AngelOfSerenity extends CardImpl { return new AngelOfSerenity(this); } } - -class AngelOfSerenityTriggeredAbility extends ZoneChangeTriggeredAbility { - - public AngelOfSerenityTriggeredAbility() { - super(Zone.BATTLEFIELD, new AngelOfSerenityEnterEffect(), "When {this} enters the battlefield, ", true); - } - - public AngelOfSerenityTriggeredAbility(AngelOfSerenityTriggeredAbility ability) { - super(ability); - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (super.checkTrigger(event, game)) { - getTargets().clear(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("up to three other target creatures"); - filter.add(new AnotherPredicate()); - TargetCreaturePermanent target1 = new TargetCreaturePermanent(0, 3, filter, false); - game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target1, this, game); - if (!target1.getTargets().isEmpty()) { - getTargets().add(target1); - - } - int leftTargets = 3 - target1.getTargets().size(); - if (leftTargets > 0) { - FilterCard filter2 = new FilterCreatureCard("up to " + leftTargets + " target creature card" + (leftTargets > 1 ? "s" : "") + " from graveyards"); - TargetCardInGraveyard target2 = new TargetCardInGraveyard(0, leftTargets, filter2); - game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target2, this, game); - if (!target2.getTargets().isEmpty()) { - getTargets().add(target2); - } - } - return true; - } - return false; - } - - @Override - public AngelOfSerenityTriggeredAbility copy() { - return new AngelOfSerenityTriggeredAbility(this); - } - -} - -class AngelOfSerenityEnterEffect extends OneShotEffect { - - public AngelOfSerenityEnterEffect() { - super(Outcome.ReturnToHand); - this.staticText = "you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards"; - } - - public AngelOfSerenityEnterEffect(final AngelOfSerenityEnterEffect effect) { - super(effect); - } - - @Override - public AngelOfSerenityEnterEffect copy() { - return new AngelOfSerenityEnterEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - boolean result = true; - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (controller != null && sourceObject != null && !source.getTargets().isEmpty()) { - UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); - for (Target target : source.getTargets()) { - if (target instanceof TargetCreaturePermanent) { - for (UUID permanentId : target.getTargets()) { - Permanent permanent = game.getPermanent(permanentId); - if (permanent != null) { - result |= controller.moveCardToExileWithInfo(permanent, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); - } - } - - } else if (target instanceof TargetCardInGraveyard) { - for (UUID cardId : target.getTargets()) { - Card card = game.getCard(cardId); - if (card != null) { - result |= controller.moveCardToExileWithInfo(card, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.GRAVEYARD, true); - } - } - } - } - } - return result; - } -} From 1bac7fc04cb743c7c2463878051d97b1ffef3c99 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 20 Nov 2018 09:46:36 -0600 Subject: [PATCH 149/167] - Fixed Soul Strings. DoUnlessAnyPlayerPays now supports X costs. --- .../java/mage/player/ai/ComputerPlayer.java | 13 +++++ Mage.Sets/src/mage/cards/s/SoulStrings.java | 5 +- Mage.Sets/src/mage/cards/v/ViashinoBey.java | 4 +- Mage.Sets/src/mage/cards/w/WarsToll.java | 5 +- .../common/DoUnlessAnyPlayerPaysEffect.java | 51 +++++++++++++++---- 5 files changed, 62 insertions(+), 16 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 4ebe78b127..3625c36769 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -861,6 +861,19 @@ public class ComputerPlayer extends PlayerImpl implements Player { } return target.isChosen(); } + + if (target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) { + List cards = new ArrayList<>(); + for (Player player : game.getPlayers().values()) { + cards.addAll(player.getGraveyard().getCards(game)); + cards.addAll(game.getBattlefield().getAllActivePermanents(new FilterPermanent(), player.getId(), game)); + } + Card card = pickTarget(cards, outcome, target, source, game); + if (card != null) { + target.addTarget(card.getId(), source, game); + return true; + } + } throw new IllegalStateException("Target wasn't handled. class:" + target.getClass().toString()); } //end of chooseTarget method diff --git a/Mage.Sets/src/mage/cards/s/SoulStrings.java b/Mage.Sets/src/mage/cards/s/SoulStrings.java index 553e607203..4dc5d88060 100644 --- a/Mage.Sets/src/mage/cards/s/SoulStrings.java +++ b/Mage.Sets/src/mage/cards/s/SoulStrings.java @@ -1,6 +1,5 @@ package mage.cards.s; -import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; @@ -11,6 +10,7 @@ import mage.filter.common.FilterCreatureCard; import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; /** * @author jmharmon @@ -23,8 +23,7 @@ public final class SoulStrings extends CardImpl { // Return two target creature cards from your graveyard to your hand unless any player pays {X}. Effect effect = new DoUnlessAnyPlayerPaysEffect( - new ReturnFromGraveyardToHandTargetEffect(), new VariableManaCost() - ); + new ReturnFromGraveyardToHandTargetEffect(), new ManacostVariableValue()); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(2, new FilterCreatureCard("creature cards from your graveyard"))); } diff --git a/Mage.Sets/src/mage/cards/v/ViashinoBey.java b/Mage.Sets/src/mage/cards/v/ViashinoBey.java index e0a3e05bd1..d3471e16e4 100644 --- a/Mage.Sets/src/mage/cards/v/ViashinoBey.java +++ b/Mage.Sets/src/mage/cards/v/ViashinoBey.java @@ -79,7 +79,9 @@ class ViashinoBeyEffect extends OneShotEffect { } else { targetDefender.add(game.getOpponents(controller.getId()).iterator().next(), game); } - controller.declareAttacker(permanent.getId(), targetDefender.getFirstTarget(), game, false); + if (permanent.canAttack(targetDefender.getFirstTarget(), game)) { + controller.declareAttacker(permanent.getId(), targetDefender.getFirstTarget(), game, false); + } }); } return false; diff --git a/Mage.Sets/src/mage/cards/w/WarsToll.java b/Mage.Sets/src/mage/cards/w/WarsToll.java index 01972bac1a..3f103a2697 100644 --- a/Mage.Sets/src/mage/cards/w/WarsToll.java +++ b/Mage.Sets/src/mage/cards/w/WarsToll.java @@ -1,4 +1,3 @@ - package mage.cards.w; import java.util.UUID; @@ -103,7 +102,9 @@ class WarsTollEffect extends OneShotEffect { filterOpponentCreatures.add(new ControllerIdPredicate(opponent.getId())); game.getBattlefield().getAllActivePermanents(CardType.CREATURE).stream().filter((permanent) -> (filterOpponentCreatures.match(permanent, source.getSourceId(), source.getControllerId(), game))).forEachOrdered((permanent) -> { //TODO: allow the player to choose between a planeswalker and player - opponent.declareAttacker(permanent.getId(), source.getControllerId(), game, false); + if (permanent.canAttack(source.getControllerId(), game)) { + opponent.declareAttacker(permanent.getId(), source.getControllerId(), game, false); + } }); return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java index 4c2208e00c..8368248a15 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common; import java.util.UUID; @@ -6,6 +5,8 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; @@ -22,15 +23,22 @@ import mage.util.CardUtil; public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect { protected Effects executingEffects = new Effects(); - private final Cost cost; + protected Cost cost; private String chooseUseText; + protected DynamicValue genericMana; + + public DoUnlessAnyPlayerPaysEffect(Effect effect, DynamicValue genericMana) { + super(Outcome.Detriment); + this.genericMana = genericMana; + this.executingEffects.add(effect); + } public DoUnlessAnyPlayerPaysEffect(Effect effect, Cost cost) { this(effect, cost, null); } public DoUnlessAnyPlayerPaysEffect(Effect effect, Cost cost, String chooseUseText) { - super(Outcome.Benefit); + super(Outcome.Neutral); this.executingEffects.add(effect); this.cost = cost; this.chooseUseText = chooseUseText; @@ -38,8 +46,13 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect { public DoUnlessAnyPlayerPaysEffect(final DoUnlessAnyPlayerPaysEffect effect) { super(effect); + if (effect.cost != null) { + this.cost = effect.cost.copy(); + } + if (effect.genericMana != null) { + this.genericMana = effect.genericMana.copy(); + } this.executingEffects = effect.executingEffects.copy(); - this.cost = effect.cost.copy(); this.chooseUseText = effect.chooseUseText; } @@ -51,11 +64,18 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); - if (controller != null && sourceObject != null) { + Cost costToPay; + if (controller != null + && sourceObject != null) { + if (cost != null) { + costToPay = cost.copy(); + } else { + costToPay = new GenericManaCost(genericMana.calculate(game, source, this)); + } String message; if (chooseUseText == null) { String effectText = executingEffects.getText(source.getModes().getMode()); - message = "Pay " + cost.getText() + " to prevent (" + effectText.substring(0, effectText.length() - 1) + ")?"; + message = "Pay " + costToPay.getText() + " to prevent (" + effectText.substring(0, effectText.length() - 1) + ")?"; } else { message = chooseUseText; } @@ -65,9 +85,10 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect { // check if any player is willing to pay for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if (player != null && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) { - cost.clearPaid(); - if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) { + if (player != null + && costToPay.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) { + costToPay.clearPaid(); + if (costToPay.pay(source, game, source.getSourceId(), player.getId(), false, null)) { if (!game.isSimulation()) { game.informPlayers(player.getLogName() + " pays the cost to prevent the effect"); } @@ -100,8 +121,18 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect { if (!staticText.isEmpty()) { return staticText; } + StringBuilder sb = new StringBuilder(); + if (cost != null) { + sb.append(cost.getText()); + } else { + sb.append("{X}"); + } + if (genericMana != null && !genericMana.getMessage().isEmpty()) { + sb.append(", where X is "); + sb.append(genericMana.getMessage()); + } String effectsText = executingEffects.getText(mode); - return effectsText.substring(0, effectsText.length() - 1) + " unless any player pays " + cost.getText(); + return effectsText.substring(0, effectsText.length() - 1) + " unless any player pays " + sb.toString(); } @Override From c61badc2c37f86bbea7359d2a82cf47f11aaea91 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 20 Nov 2018 15:22:58 -0600 Subject: [PATCH 150/167] - Fixed Stadium Vendors. --- .../src/mage/cards/s/StadiumVendors.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/StadiumVendors.java b/Mage.Sets/src/mage/cards/s/StadiumVendors.java index 04ebe8dad8..c95788ca69 100644 --- a/Mage.Sets/src/mage/cards/s/StadiumVendors.java +++ b/Mage.Sets/src/mage/cards/s/StadiumVendors.java @@ -1,4 +1,3 @@ - package mage.cards.s; import java.util.UUID; @@ -65,21 +64,22 @@ class StadiumVendorsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { return false; } TargetPlayer target = new TargetPlayer(1, 1, true); - if (!controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { - return false; + if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + Player player = game.getPlayer(target.getFirstTarget()); + ChoiceColor colorChoice = new ChoiceColor(true); + if (player == null + || !player.choose(Outcome.Benefit, colorChoice, game)) { + return false; + } + Effect effect = new AddManaToManaPoolTargetControllerEffect(colorChoice.getMana(2), "that player's"); + effect.setTargetPointer(new FixedTarget(player.getId(), game)); + return effect.apply(game, source); } - Player player = game.getPlayer(target.getFirstTarget()); - ChoiceColor colorChoice = new ChoiceColor(true); - if (player == null || !player.choose(Outcome.Benefit, colorChoice, game)) { - return false; - } - Effect effect = new AddManaToManaPoolTargetControllerEffect(colorChoice.getMana(2), "that player's"); - effect.setTargetPointer(new FixedTarget(player.getId(), game)); - return effect.apply(game, source); + return false; } } From 8185bdf62b7467d1f3b4a0bd2958f5276d4070f4 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 21 Nov 2018 02:54:08 +0400 Subject: [PATCH 151/167] * Updated Canadian Highlander format to November 19th, 2018 version (#5436); --- .../Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java index 89581e8aeb..da4955be6a 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java @@ -45,6 +45,7 @@ public class CanadianHighlander extends Constructed { pointMap.put("Personal Tutor", 1); pointMap.put("Protean Hulk", 3); pointMap.put("Sol Ring", 3); + pointMap.put("Spellseeker", 1); pointMap.put("Stoneforge Mystic", 1); pointMap.put("Strip Mine", 2); pointMap.put("Summoner's Pact", 2); From 2bf0c1d98ef8ceb9af77b22261c6e4bfe02a4347 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 21 Nov 2018 02:57:50 +0400 Subject: [PATCH 152/167] Tests: improved tests performance --- .../base/impl/CardTestPlayerAPIImpl.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index c986d0df0f..b858d8609b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -1,11 +1,11 @@ package org.mage.test.serverside.base.impl; -import mage.MageInt; import mage.Mana; import mage.ObjectColor; import mage.abilities.Ability; import mage.cards.Card; import mage.cards.decks.Deck; +import mage.cards.decks.DeckCardLists; import mage.cards.decks.importer.DeckImporterUtil; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; @@ -66,7 +66,6 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement protected String deckNameD; protected enum ExpectedType { - TURN_NUMBER, RESULT, LIFE, @@ -167,12 +166,21 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement protected TestPlayer createPlayer(Game game, TestPlayer player, String name, String deckName) throws GameException { player = createNewPlayer(name, game.getRangeOfInfluence()); player.setTestMode(true); + logger.debug("Loading deck..."); - Deck deck = Deck.load(DeckImporterUtil.importDeck(deckName), false, false); + DeckCardLists list; + if (loadedDeckCardLists.containsKey(deckName)) { + list = loadedDeckCardLists.get(deckName); + } else { + list = DeckImporterUtil.importDeck(deckName); + loadedDeckCardLists.put(deckName, list); + } + Deck deck = Deck.load(list, false, false); logger.debug("Done!"); if (deck.getCards().size() < 40) { throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck.getCards().size()); } + game.loadCards(deck.getCards(), player.getId()); game.loadCards(deck.getSideboard(), player.getId()); game.addPlayer(player, deck); From 7c2738cf9f421516f23755bd933716c7c9d4c9d3 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 21 Nov 2018 02:59:24 +0400 Subject: [PATCH 153/167] Merge fix --- .../org/mage/test/serverside/base/MageTestPlayerBase.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java index 37da99ab42..b514cc68b4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java @@ -10,6 +10,8 @@ import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; import mage.cards.Card; +import mage.cards.decks.Deck; +import mage.cards.decks.DeckCardLists; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; import mage.constants.PhaseStep; @@ -54,6 +56,8 @@ public abstract class MageTestPlayerBase { protected Map> commands = new HashMap<>(); + protected static Map loadedDeckCardLists = new HashMap<>(); // test decks buffer + protected TestPlayer playerA; protected TestPlayer playerB; protected TestPlayer playerC; From c7a3e5308371e0cdc831bf6b6d572a098a50c2f4 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 20 Nov 2018 17:43:26 -0600 Subject: [PATCH 154/167] - Fix for Bug #5435. Specific to "must attack" code. --- .../main/java/mage/game/combat/Combat.java | 47 +++++++++++-------- .../main/java/mage/players/PlayerImpl.java | 4 +- .../mage/target/common/TargetDefender.java | 24 ++++++---- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/Mage/src/main/java/mage/game/combat/Combat.java b/Mage/src/main/java/mage/game/combat/Combat.java index 7a1c7a71d8..08157890e1 100644 --- a/Mage/src/main/java/mage/game/combat/Combat.java +++ b/Mage/src/main/java/mage/game/combat/Combat.java @@ -1,4 +1,3 @@ - package mage.game.combat; import mage.MageObject; @@ -108,8 +107,8 @@ public class Combat implements Serializable, Copyable { } /** - * Get all possible defender (players and plainwalkers) That does not mean - * neccessarly mean that they are really attacked + * Get all possible defender (players and planeswalkers) That does not mean + * necessarily mean that they are really attacked * * @return */ @@ -251,11 +250,14 @@ public class Combat implements Serializable, Copyable { game.getCombat().checkAttackRequirements(player, game); boolean firstTime = true; do { - if (!firstTime || !game.getPlayer(game.getActivePlayerId()).getAvailableAttackers(game).isEmpty()) { + if (!firstTime + || !game.getPlayer(game.getActivePlayerId()).getAvailableAttackers(game).isEmpty()) { player.selectAttackers(game, attackingPlayerId); } firstTime = false; - if (game.isPaused() || game.checkIfGameIsOver() || game.executingRollback()) { + if (game.isPaused() + || game.checkIfGameIsOver() + || game.executingRollback()) { return; } // because of possible undo during declare attackers it's neccassary to call here the methods with "game.getCombat()." to get the current combat object!!! @@ -338,7 +340,7 @@ public class Combat implements Serializable, Copyable { || !player.chooseUse(Outcome.Benefit, "Do you wish to " + (isBanded ? "band " + attacker.getLogName() + " with another " : "form a band with " + attacker.getLogName() + " and an ") + "attacking creature?", null, game)) { break; } - + if (canBand && canBandWithOther) { if (player.chooseUse(Outcome.Detriment, "Choose type of banding ability to apply:", attacker.getLogName(), "Banding", "Bands with other", null, game)) { canBandWithOther = false; @@ -359,13 +361,13 @@ public class Combat implements Serializable, Copyable { filter.add(Predicates.or(predicates)); } } - + if (target.choose(Outcome.Benefit, attackingPlayerId, null, game)) { isBanded = true; for (UUID targetId : target.getTargets()) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - + for (UUID bandedId : attacker.getBandedCards()) { permanent.addBandedCard(bandedId); Permanent banded = game.getPermanent(bandedId); @@ -391,7 +393,7 @@ public class Combat implements Serializable, Copyable { canBand = false; } } - + } } } @@ -454,11 +456,16 @@ public class Combat implements Serializable, Copyable { if (defenders.size() == 1) { player.declareAttacker(creature.getId(), defenders.iterator().next(), game, false); } else { - TargetDefender target = new TargetDefender(defenders, creature.getId()); - target.setRequired(true); - target.setTargetName("planeswalker or player for " + creature.getLogName() + " to attack"); - if (player.chooseTarget(Outcome.Damage, target, null, game)) { - player.declareAttacker(creature.getId(), target.getFirstTarget(), game, false); + if (!player.isHuman()) { // computer only for multiple defenders + player.declareAttacker(creature.getId(), defenders.iterator().next(), game, false); + } else { // human players only for multiple defenders + TargetDefender target = new TargetDefender(defenders, creature.getId()); + target.setRequired(true); + target.setTargetName("planeswalker or player for " + creature.getLogName() + " to attack"); + if (player.chooseTarget(Outcome.Damage, target, null, game)) { + System.out.println("The player " + player.getName() + " declares an attacker here. " + creature.getName()); + player.declareAttacker(creature.getId(), target.getFirstTarget(), game, false); + } } } } else { @@ -550,7 +557,7 @@ public class Combat implements Serializable, Copyable { * Handle the blocker selection process * * @param blockController player that controlls how to block, if null the - * defender is the controller + * defender is the controller * @param game */ public void selectBlockers(Player blockController, Game game) { @@ -1342,10 +1349,10 @@ public class Combat implements Serializable, Copyable { if (defenderAttackedBy.size() >= defendingPlayer.getMaxAttackedBy()) { Player attackingPlayer = game.getPlayer(game.getControllerId(attackerId)); if (attackingPlayer != null && !game.isSimulation()) { - game.informPlayer(attackingPlayer, "No more than " + - CardUtil.numberToText(defendingPlayer.getMaxAttackedBy()) + - " creatures can attack " + - defendingPlayer.getLogName()); + game.informPlayer(attackingPlayer, "No more than " + + CardUtil.numberToText(defendingPlayer.getMaxAttackedBy()) + + " creatures can attack " + + defendingPlayer.getLogName()); } return false; } @@ -1375,7 +1382,7 @@ public class Combat implements Serializable, Copyable { * @param playerId * @param game * @param solveBanding check whether also add creatures banded with - * attackerId + * attackerId */ public void addBlockingGroup(UUID blockerId, UUID attackerId, UUID playerId, Game game, boolean solveBanding) { Permanent blocker = game.getPermanent(blockerId); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index a3ad806816..ec355521d9 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -2372,7 +2372,9 @@ public abstract class PlayerImpl implements Player, Serializable { setStoredBookmark(game.bookmarkState()); // makes it possible to UNDO a declared attacker with costs from e.g. Propaganda } Permanent attacker = game.getPermanent(attackerId); - if (attacker != null && attacker.canAttack(defenderId, game) && attacker.isControlledBy(playerId)) { + if (attacker != null + && attacker.canAttack(defenderId, game) + && attacker.isControlledBy(playerId)) { if (!game.getCombat().declareAttacker(attackerId, defenderId, playerId, game)) { game.undo(playerId); } diff --git a/Mage/src/main/java/mage/target/common/TargetDefender.java b/Mage/src/main/java/mage/target/common/TargetDefender.java index 3d48481d59..863c419b28 100644 --- a/Mage/src/main/java/mage/target/common/TargetDefender.java +++ b/Mage/src/main/java/mage/target/common/TargetDefender.java @@ -68,7 +68,8 @@ public class TargetDefender extends TargetImpl { } } for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_PLANESWALKER, sourceControllerId, game)) { - if ((notTarget || permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) + if ((notTarget + || permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) && filter.match(permanent, game)) { count++; if (count >= this.minNumberOfTargets) { @@ -84,7 +85,8 @@ public class TargetDefender extends TargetImpl { int count = 0; for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) { Player player = game.getPlayer(playerId); - if (player != null && filter.match(player, game)) { + if (player != null + && filter.match(player, game)) { count++; if (count >= this.minNumberOfTargets) { return true; @@ -109,13 +111,15 @@ public class TargetDefender extends TargetImpl { for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) { Player player = game.getPlayer(playerId); if (player != null - && (notTarget || player.canBeTargetedBy(targetSource, sourceControllerId, game)) + && (notTarget + || player.canBeTargetedBy(targetSource, sourceControllerId, game)) && filter.match(player, game)) { possibleTargets.add(playerId); } } for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_PLANESWALKER, sourceControllerId, game)) { - if ((notTarget || permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) + if ((notTarget + || permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) && filter.match(permanent, game)) { possibleTargets.add(permanent.getId()); } @@ -128,7 +132,8 @@ public class TargetDefender extends TargetImpl { Set possibleTargets = new HashSet<>(); for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) { Player player = game.getPlayer(playerId); - if (player != null && filter.match(player, game)) { + if (player != null + && filter.match(player, game)) { possibleTargets.add(playerId); } } @@ -162,7 +167,8 @@ public class TargetDefender extends TargetImpl { return filter.match(player, game); } Permanent permanent = game.getPermanent(id); - return permanent != null && filter.match(permanent, game); + return permanent != null + && filter.match(permanent, game); } @Override @@ -170,7 +176,8 @@ public class TargetDefender extends TargetImpl { Player player = game.getPlayer(id); MageObject targetSource = game.getObject(attackerId); if (player != null) { - return (notTarget || player.canBeTargetedBy(targetSource, (source == null ? null : source.getControllerId()), game)) + return (notTarget + || player.canBeTargetedBy(targetSource, (source == null ? null : source.getControllerId()), game)) && filter.match(player, game); } Permanent permanent = game.getPermanent(id); // planeswalker @@ -180,7 +187,8 @@ public class TargetDefender extends TargetImpl { if (source != null) { controllerId = source.getControllerId(); } - return (notTarget || permanent.canBeTargetedBy(targetSource, controllerId, game)) + return (notTarget + || permanent.canBeTargetedBy(targetSource, controllerId, game)) && filter.match(permanent, game); } return false; From 738cb59eaf59b2ff523e8978b40a6a724542de46 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Thu, 22 Nov 2018 19:17:18 +0400 Subject: [PATCH 155/167] Added all cards to Ultimate Masters --- Mage.Sets/src/mage/sets/UltimateMasters.java | 214 ++++++++++++++++++- 1 file changed, 213 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/UltimateMasters.java b/Mage.Sets/src/mage/sets/UltimateMasters.java index a97affe33b..7e39b5da52 100644 --- a/Mage.Sets/src/mage/sets/UltimateMasters.java +++ b/Mage.Sets/src/mage/sets/UltimateMasters.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.ExpansionSet; @@ -27,46 +26,259 @@ public final class UltimateMasters extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Aethersnipe", 44, Rarity.COMMON, mage.cards.a.Aethersnipe.class)); + cards.add(new SetCardInfo("Akroan Crusader", 121, Rarity.COMMON, mage.cards.a.AkroanCrusader.class)); + cards.add(new SetCardInfo("All Is Dust", 1, Rarity.RARE, mage.cards.a.AllIsDust.class)); + cards.add(new SetCardInfo("Ancestor's Chosen", 9, Rarity.UNCOMMON, mage.cards.a.AncestorsChosen.class)); cards.add(new SetCardInfo("Ancient Tomb", 236, Rarity.RARE, mage.cards.a.AncientTomb.class)); + cards.add(new SetCardInfo("Angel of Despair", 196, Rarity.UNCOMMON, mage.cards.a.AngelOfDespair.class)); + cards.add(new SetCardInfo("Angelic Renewal", 10, Rarity.COMMON, mage.cards.a.AngelicRenewal.class)); + cards.add(new SetCardInfo("Anger", 122, Rarity.UNCOMMON, mage.cards.a.Anger.class)); + cards.add(new SetCardInfo("Appetite for Brains", 83, Rarity.UNCOMMON, mage.cards.a.AppetiteForBrains.class)); + cards.add(new SetCardInfo("Apprentice Necromancer", 84, Rarity.UNCOMMON, mage.cards.a.ApprenticeNecromancer.class)); + cards.add(new SetCardInfo("Archaeomancer", 45, Rarity.COMMON, mage.cards.a.Archaeomancer.class)); + cards.add(new SetCardInfo("Arena Athlete", 123, Rarity.COMMON, mage.cards.a.ArenaAthlete.class)); + cards.add(new SetCardInfo("Artisan of Kozilek", 2, Rarity.UNCOMMON, mage.cards.a.ArtisanOfKozilek.class)); + cards.add(new SetCardInfo("Back to Basics", 46, Rarity.RARE, mage.cards.b.BackToBasics.class)); cards.add(new SetCardInfo("Balefire Dragon", 124, Rarity.MYTHIC, mage.cards.b.BalefireDragon.class)); + cards.add(new SetCardInfo("Basking Rootwalla", 156, Rarity.COMMON, mage.cards.b.BaskingRootwalla.class)); + cards.add(new SetCardInfo("Beckon Apparition", 211, Rarity.COMMON, mage.cards.b.BeckonApparition.class)); + cards.add(new SetCardInfo("Become Immense", 157, Rarity.UNCOMMON, mage.cards.b.BecomeImmense.class)); cards.add(new SetCardInfo("Bitterblossom", 85, Rarity.MYTHIC, mage.cards.b.Bitterblossom.class)); + cards.add(new SetCardInfo("Blast of Genius", 197, Rarity.UNCOMMON, mage.cards.b.BlastOfGenius.class)); + cards.add(new SetCardInfo("Bloodflow Connoisseur", 86, Rarity.COMMON, mage.cards.b.BloodflowConnoisseur.class)); + cards.add(new SetCardInfo("Boar Umbra", 158, Rarity.UNCOMMON, mage.cards.b.BoarUmbra.class)); + cards.add(new SetCardInfo("Boneyard Wurm", 159, Rarity.UNCOMMON, mage.cards.b.BoneyardWurm.class)); + cards.add(new SetCardInfo("Brawn", 160, Rarity.UNCOMMON, mage.cards.b.Brawn.class)); + cards.add(new SetCardInfo("Brazen Scourge", 125, Rarity.UNCOMMON, mage.cards.b.BrazenScourge.class)); + cards.add(new SetCardInfo("Bridge from Below", 87, Rarity.RARE, mage.cards.b.BridgeFromBelow.class)); + cards.add(new SetCardInfo("Buried Alive", 88, Rarity.UNCOMMON, mage.cards.b.BuriedAlive.class)); + cards.add(new SetCardInfo("Canker Abomination", 212, Rarity.COMMON, mage.cards.c.CankerAbomination.class)); + cards.add(new SetCardInfo("Cathodion", 226, Rarity.COMMON, mage.cards.c.Cathodion.class)); cards.add(new SetCardInfo("Cavern of Souls", 237, Rarity.MYTHIC, mage.cards.c.CavernOfSouls.class)); cards.add(new SetCardInfo("Celestial Colonnade", 238, Rarity.RARE, mage.cards.c.CelestialColonnade.class)); + cards.add(new SetCardInfo("Chainer's Edict", 89, Rarity.UNCOMMON, mage.cards.c.ChainersEdict.class)); + cards.add(new SetCardInfo("Circular Logic", 47, Rarity.UNCOMMON, mage.cards.c.CircularLogic.class)); + cards.add(new SetCardInfo("Conflagrate", 126, Rarity.UNCOMMON, mage.cards.c.Conflagrate.class)); + cards.add(new SetCardInfo("Containment Priest", 11, Rarity.RARE, mage.cards.c.ContainmentPriest.class)); + cards.add(new SetCardInfo("Conviction", 12, Rarity.COMMON, mage.cards.c.Conviction.class)); + cards.add(new SetCardInfo("Countersquall", 198, Rarity.UNCOMMON, mage.cards.c.Countersquall.class)); cards.add(new SetCardInfo("Creeping Tar Pit", 239, Rarity.RARE, mage.cards.c.CreepingTarPit.class)); + cards.add(new SetCardInfo("Crow of Dark Tidings", 90, Rarity.COMMON, mage.cards.c.CrowOfDarkTidings.class)); + cards.add(new SetCardInfo("Crushing Canopy", 161, Rarity.COMMON, mage.cards.c.CrushingCanopy.class)); + cards.add(new SetCardInfo("Dakmor Salvage", 240, Rarity.UNCOMMON, mage.cards.d.DakmorSalvage.class)); + cards.add(new SetCardInfo("Dark Dabbling", 91, Rarity.COMMON, mage.cards.d.DarkDabbling.class)); cards.add(new SetCardInfo("Dark Depths", 241, Rarity.MYTHIC, mage.cards.d.DarkDepths.class)); + cards.add(new SetCardInfo("Dawn Charm", 13, Rarity.UNCOMMON, mage.cards.d.DawnCharm.class)); + cards.add(new SetCardInfo("Daybreak Coronet", 14, Rarity.RARE, mage.cards.d.DaybreakCoronet.class)); + cards.add(new SetCardInfo("Death Denied", 92, Rarity.COMMON, mage.cards.d.DeathDenied.class)); + cards.add(new SetCardInfo("Defy Gravity", 48, Rarity.COMMON, mage.cards.d.DefyGravity.class)); cards.add(new SetCardInfo("Demonic Tutor", 93, Rarity.RARE, mage.cards.d.DemonicTutor.class)); + cards.add(new SetCardInfo("Deranged Assistant", 49, Rarity.COMMON, mage.cards.d.DerangedAssistant.class)); + cards.add(new SetCardInfo("Desolate Lighthouse", 242, Rarity.RARE, mage.cards.d.DesolateLighthouse.class)); + cards.add(new SetCardInfo("Desperate Ritual", 127, Rarity.UNCOMMON, mage.cards.d.DesperateRitual.class)); + cards.add(new SetCardInfo("Devoted Druid", 162, Rarity.UNCOMMON, mage.cards.d.DevotedDruid.class)); + cards.add(new SetCardInfo("Dig Through Time", 50, Rarity.RARE, mage.cards.d.DigThroughTime.class)); + cards.add(new SetCardInfo("Dimir Guildmage", 213, Rarity.COMMON, mage.cards.d.DimirGuildmage.class)); + cards.add(new SetCardInfo("Disrupting Shoal", 51, Rarity.RARE, mage.cards.d.DisruptingShoal.class)); + cards.add(new SetCardInfo("Double Cleave", 214, Rarity.COMMON, mage.cards.d.DoubleCleave.class)); + cards.add(new SetCardInfo("Dreamscape Artist", 52, Rarity.UNCOMMON, mage.cards.d.DreamscapeArtist.class)); + cards.add(new SetCardInfo("Eel Umbra", 53, Rarity.COMMON, mage.cards.e.EelUmbra.class)); + cards.add(new SetCardInfo("Eldrazi Conscription", 3, Rarity.RARE, mage.cards.e.EldraziConscription.class)); + cards.add(new SetCardInfo("Emancipation Angel", 15, Rarity.UNCOMMON, mage.cards.e.EmancipationAngel.class)); cards.add(new SetCardInfo("Emrakul, the Aeons Torn", 4, Rarity.MYTHIC, mage.cards.e.EmrakulTheAeonsTorn.class)); cards.add(new SetCardInfo("Engineered Explosives", 227, Rarity.RARE, mage.cards.e.EngineeredExplosives.class)); cards.add(new SetCardInfo("Entomb", 94, Rarity.RARE, mage.cards.e.Entomb.class)); cards.add(new SetCardInfo("Eternal Witness", 163, Rarity.UNCOMMON, mage.cards.e.EternalWitness.class)); + cards.add(new SetCardInfo("Faith's Fetters", 16, Rarity.COMMON, mage.cards.f.FaithsFetters.class)); + cards.add(new SetCardInfo("Faithless Looting", 128, Rarity.COMMON, mage.cards.f.FaithlessLooting.class)); + cards.add(new SetCardInfo("Fauna Shaman", 164, Rarity.RARE, mage.cards.f.FaunaShaman.class)); + cards.add(new SetCardInfo("Fecundity", 165, Rarity.UNCOMMON, mage.cards.f.Fecundity.class)); + cards.add(new SetCardInfo("Fiend Hunter", 17, Rarity.UNCOMMON, mage.cards.f.FiendHunter.class)); + cards.add(new SetCardInfo("Fiery Temper", 129, Rarity.COMMON, mage.cards.f.FieryTemper.class)); + cards.add(new SetCardInfo("Fire // Ice", 225, Rarity.COMMON, mage.cards.f.FireIce.class)); + cards.add(new SetCardInfo("Firewing Phoenix", 130, Rarity.UNCOMMON, mage.cards.f.FirewingPhoenix.class)); + cards.add(new SetCardInfo("Flagstones of Trokair", 243, Rarity.RARE, mage.cards.f.FlagstonesOfTrokair.class)); + cards.add(new SetCardInfo("Flight of Fancy", 54, Rarity.COMMON, mage.cards.f.FlightOfFancy.class)); + cards.add(new SetCardInfo("Foil", 55, Rarity.COMMON, mage.cards.f.Foil.class)); + cards.add(new SetCardInfo("Forbidden Alchemy", 56, Rarity.UNCOMMON, mage.cards.f.ForbiddenAlchemy.class)); + cards.add(new SetCardInfo("Frantic Search", 57, Rarity.COMMON, mage.cards.f.FranticSearch.class)); cards.add(new SetCardInfo("Fulminator Mage", 215, Rarity.RARE, mage.cards.f.FulminatorMage.class)); + cards.add(new SetCardInfo("Fume Spitter", 95, Rarity.COMMON, mage.cards.f.FumeSpitter.class)); + cards.add(new SetCardInfo("Furnace Celebration", 131, Rarity.UNCOMMON, mage.cards.f.FurnaceCelebration.class)); cards.add(new SetCardInfo("Gaddock Teeg", 199, Rarity.RARE, mage.cards.g.GaddockTeeg.class)); + cards.add(new SetCardInfo("Gamble", 132, Rarity.RARE, mage.cards.g.Gamble.class)); + cards.add(new SetCardInfo("Garna, the Bloodflame", 200, Rarity.UNCOMMON, mage.cards.g.GarnaTheBloodflame.class)); + cards.add(new SetCardInfo("Generator Servant", 133, Rarity.COMMON, mage.cards.g.GeneratorServant.class)); + cards.add(new SetCardInfo("Ghoulcaller's Accomplice", 96, Rarity.COMMON, mage.cards.g.GhoulcallersAccomplice.class)); + cards.add(new SetCardInfo("Ghoulsteed", 97, Rarity.UNCOMMON, mage.cards.g.Ghoulsteed.class)); + cards.add(new SetCardInfo("Glen Elendra Archmage", 58, Rarity.RARE, mage.cards.g.GlenElendraArchmage.class)); + cards.add(new SetCardInfo("Gods Willing", 18, Rarity.COMMON, mage.cards.g.GodsWilling.class)); + cards.add(new SetCardInfo("Golgari Brownscale", 166, Rarity.COMMON, mage.cards.g.GolgariBrownscale.class)); + cards.add(new SetCardInfo("Golgari Charm", 201, Rarity.UNCOMMON, mage.cards.g.GolgariCharm.class)); + cards.add(new SetCardInfo("Golgari Grave-Troll", 167, Rarity.RARE, mage.cards.g.GolgariGraveTroll.class)); + cards.add(new SetCardInfo("Golgari Thug", 98, Rarity.UNCOMMON, mage.cards.g.GolgariThug.class)); cards.add(new SetCardInfo("Goryo's Vengeance", 99, Rarity.RARE, mage.cards.g.GoryosVengeance.class)); + cards.add(new SetCardInfo("Grave Scrabbler", 100, Rarity.COMMON, mage.cards.g.GraveScrabbler.class)); + cards.add(new SetCardInfo("Grave Strength", 101, Rarity.UNCOMMON, mage.cards.g.GraveStrength.class)); + cards.add(new SetCardInfo("Groundskeeper", 168, Rarity.COMMON, mage.cards.g.Groundskeeper.class)); + cards.add(new SetCardInfo("Gurmag Angler", 102, Rarity.COMMON, mage.cards.g.GurmagAngler.class)); + cards.add(new SetCardInfo("Heap Doll", 228, Rarity.UNCOMMON, mage.cards.h.HeapDoll.class)); + cards.add(new SetCardInfo("Heliod's Pilgrim", 19, Rarity.COMMON, mage.cards.h.HeliodsPilgrim.class)); + cards.add(new SetCardInfo("Hero of Iroas", 20, Rarity.UNCOMMON, mage.cards.h.HeroOfIroas.class)); + cards.add(new SetCardInfo("Hero of Leina Tower", 169, Rarity.UNCOMMON, mage.cards.h.HeroOfLeinaTower.class)); + cards.add(new SetCardInfo("Hissing Iguanar", 134, Rarity.COMMON, mage.cards.h.HissingIguanar.class)); + cards.add(new SetCardInfo("Hooting Mandrills", 170, Rarity.COMMON, mage.cards.h.HootingMandrills.class)); + cards.add(new SetCardInfo("Hyena Umbra", 21, Rarity.COMMON, mage.cards.h.HyenaUmbra.class)); + cards.add(new SetCardInfo("Icatian Crier", 22, Rarity.COMMON, mage.cards.i.IcatianCrier.class)); + cards.add(new SetCardInfo("Ingot Chewer", 135, Rarity.COMMON, mage.cards.i.IngotChewer.class)); + cards.add(new SetCardInfo("Iridescent Drake", 59, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); + cards.add(new SetCardInfo("Just the Wind", 60, Rarity.COMMON, mage.cards.j.JustTheWind.class)); cards.add(new SetCardInfo("Karakas", 244, Rarity.MYTHIC, mage.cards.k.Karakas.class)); cards.add(new SetCardInfo("Karn Liberated", 5, Rarity.MYTHIC, mage.cards.k.KarnLiberated.class)); cards.add(new SetCardInfo("Kitchen Finks", 216, Rarity.UNCOMMON, mage.cards.k.KitchenFinks.class)); + cards.add(new SetCardInfo("Kodama's Reach", 171, Rarity.COMMON, mage.cards.k.KodamasReach.class)); cards.add(new SetCardInfo("Kozilek, Butcher of Truth", 6, Rarity.MYTHIC, mage.cards.k.KozilekButcherOfTruth.class)); + cards.add(new SetCardInfo("Laboratory Maniac", 61, Rarity.UNCOMMON, mage.cards.l.LaboratoryManiac.class)); + cards.add(new SetCardInfo("Last Gasp", 103, Rarity.COMMON, mage.cards.l.LastGasp.class)); + cards.add(new SetCardInfo("Lava Spike", 136, Rarity.UNCOMMON, mage.cards.l.LavaSpike.class)); cards.add(new SetCardInfo("Lavaclaw Reaches", 245, Rarity.RARE, mage.cards.l.LavaclawReaches.class)); cards.add(new SetCardInfo("Leovold, Emissary of Trest", 202, Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); cards.add(new SetCardInfo("Life from the Loam", 172, Rarity.RARE, mage.cards.l.LifeFromTheLoam.class)); cards.add(new SetCardInfo("Liliana of the Veil", 104, Rarity.MYTHIC, mage.cards.l.LilianaOfTheVeil.class)); + cards.add(new SetCardInfo("Living Lore", 62, Rarity.UNCOMMON, mage.cards.l.LivingLore.class)); cards.add(new SetCardInfo("Lord of Extinction", 203, Rarity.MYTHIC, mage.cards.l.LordOfExtinction.class)); + cards.add(new SetCardInfo("Lotus-Eye Mystics", 23, Rarity.COMMON, mage.cards.l.LotusEyeMystics.class)); + cards.add(new SetCardInfo("Mad Prophet", 137, Rarity.COMMON, mage.cards.m.MadProphet.class)); cards.add(new SetCardInfo("Maelstrom Pulse", 204, Rarity.RARE, mage.cards.m.MaelstromPulse.class)); + cards.add(new SetCardInfo("Mage-Ring Network", 246, Rarity.UNCOMMON, mage.cards.m.MageRingNetwork.class)); + cards.add(new SetCardInfo("Magmaw", 138, Rarity.UNCOMMON, mage.cards.m.Magmaw.class)); + cards.add(new SetCardInfo("Magus of the Bazaar", 63, Rarity.RARE, mage.cards.m.MagusOfTheBazaar.class)); + cards.add(new SetCardInfo("Mahamoti Djinn", 64, Rarity.UNCOMMON, mage.cards.m.MahamotiDjinn.class)); + cards.add(new SetCardInfo("Malevolent Whispers", 139, Rarity.UNCOMMON, mage.cards.m.MalevolentWhispers.class)); + cards.add(new SetCardInfo("Mammoth Umbra", 24, Rarity.COMMON, mage.cards.m.MammothUmbra.class)); cards.add(new SetCardInfo("Mana Vault", 229, Rarity.MYTHIC, mage.cards.m.ManaVault.class)); + cards.add(new SetCardInfo("Marang River Prowler", 65, Rarity.UNCOMMON, mage.cards.m.MarangRiverProwler.class)); + cards.add(new SetCardInfo("Mark of the Vampire", 105, Rarity.COMMON, mage.cards.m.MarkOfTheVampire.class)); + cards.add(new SetCardInfo("Martyr of Sands", 25, Rarity.COMMON, mage.cards.m.MartyrOfSands.class)); cards.add(new SetCardInfo("Mikaeus, the Unhallowed", 106, Rarity.MYTHIC, mage.cards.m.MikaeusTheUnhallowed.class)); + cards.add(new SetCardInfo("Miming Slime", 173, Rarity.COMMON, mage.cards.m.MimingSlime.class)); + cards.add(new SetCardInfo("Miraculous Recovery", 26, Rarity.UNCOMMON, mage.cards.m.MiraculousRecovery.class)); + cards.add(new SetCardInfo("Mistveil Plains", 247, Rarity.UNCOMMON, mage.cards.m.MistveilPlains.class)); + cards.add(new SetCardInfo("Moan of the Unhallowed", 107, Rarity.COMMON, mage.cards.m.MoanOfTheUnhallowed.class)); + cards.add(new SetCardInfo("Molten Birth", 140, Rarity.COMMON, mage.cards.m.MoltenBirth.class)); + cards.add(new SetCardInfo("Murderous Redcap", 217, Rarity.UNCOMMON, mage.cards.m.MurderousRedcap.class)); + cards.add(new SetCardInfo("Myr Servitor", 230, Rarity.COMMON, mage.cards.m.MyrServitor.class)); + cards.add(new SetCardInfo("Mystic Retrieval", 66, Rarity.UNCOMMON, mage.cards.m.MysticRetrieval.class)); + cards.add(new SetCardInfo("Nightbird's Clutches", 141, Rarity.COMMON, mage.cards.n.NightbirdsClutches.class)); cards.add(new SetCardInfo("Noble Hierarch", 174, Rarity.RARE, mage.cards.n.NobleHierarch.class)); + cards.add(new SetCardInfo("Nourishing Shoal", 175, Rarity.RARE, mage.cards.n.NourishingShoal.class)); + cards.add(new SetCardInfo("Offalsnout", 108, Rarity.COMMON, mage.cards.o.Offalsnout.class)); + cards.add(new SetCardInfo("Olivia's Dragoon", 109, Rarity.COMMON, mage.cards.o.OliviasDragoon.class)); + cards.add(new SetCardInfo("Patchwork Gnomes", 231, Rarity.COMMON, mage.cards.p.PatchworkGnomes.class)); + cards.add(new SetCardInfo("Pattern of Rebirth", 176, Rarity.RARE, mage.cards.p.PatternOfRebirth.class)); + cards.add(new SetCardInfo("Penumbra Wurm", 177, Rarity.UNCOMMON, mage.cards.p.PenumbraWurm.class)); + cards.add(new SetCardInfo("Phalanx Leader", 27, Rarity.UNCOMMON, mage.cards.p.PhalanxLeader.class)); + cards.add(new SetCardInfo("Phyrexian Altar", 232, Rarity.RARE, mage.cards.p.PhyrexianAltar.class)); + cards.add(new SetCardInfo("Phyrexian Tower", 248, Rarity.RARE, mage.cards.p.PhyrexianTower.class)); cards.add(new SetCardInfo("Platinum Emperion", 233, Rarity.MYTHIC, mage.cards.p.PlatinumEmperion.class)); + cards.add(new SetCardInfo("Plumeveil", 218, Rarity.UNCOMMON, mage.cards.p.Plumeveil.class)); + cards.add(new SetCardInfo("Prey Upon", 178, Rarity.COMMON, mage.cards.p.PreyUpon.class)); + cards.add(new SetCardInfo("Prismatic Lens", 234, Rarity.UNCOMMON, mage.cards.p.PrismaticLens.class)); + cards.add(new SetCardInfo("Pulse of Murasa", 179, Rarity.COMMON, mage.cards.p.PulseOfMurasa.class)); cards.add(new SetCardInfo("Raging Ravine", 249, Rarity.RARE, mage.cards.r.RagingRavine.class)); + cards.add(new SetCardInfo("Raid Bombardment", 142, Rarity.COMMON, mage.cards.r.RaidBombardment.class)); + cards.add(new SetCardInfo("Rakdos Shred-Freak", 219, Rarity.COMMON, mage.cards.r.RakdosShredFreak.class)); + cards.add(new SetCardInfo("Rally the Peasants", 28, Rarity.UNCOMMON, mage.cards.r.RallyThePeasants.class)); cards.add(new SetCardInfo("Reanimate", 110, Rarity.RARE, mage.cards.r.Reanimate.class)); + cards.add(new SetCardInfo("Reckless Charge", 143, Rarity.COMMON, mage.cards.r.RecklessCharge.class)); + cards.add(new SetCardInfo("Reckless Wurm", 144, Rarity.COMMON, mage.cards.r.RecklessWurm.class)); + cards.add(new SetCardInfo("Repel the Darkness", 29, Rarity.COMMON, mage.cards.r.RepelTheDarkness.class)); + cards.add(new SetCardInfo("Resurrection", 30, Rarity.COMMON, mage.cards.r.Resurrection.class)); + cards.add(new SetCardInfo("Reveillark", 31, Rarity.RARE, mage.cards.r.Reveillark.class)); + cards.add(new SetCardInfo("Reviving Vapors", 205, Rarity.UNCOMMON, mage.cards.r.RevivingVapors.class)); + cards.add(new SetCardInfo("Reya Dawnbringer", 32, Rarity.RARE, mage.cards.r.ReyaDawnbringer.class)); + cards.add(new SetCardInfo("Rise from the Tides", 67, Rarity.UNCOMMON, mage.cards.r.RiseFromTheTides.class)); + cards.add(new SetCardInfo("Rogue's Passage", 250, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); + cards.add(new SetCardInfo("Rolling Temblor", 145, Rarity.UNCOMMON, mage.cards.r.RollingTemblor.class)); + cards.add(new SetCardInfo("Ronom Unicorn", 33, Rarity.COMMON, mage.cards.r.RonomUnicorn.class)); + cards.add(new SetCardInfo("Rune Snag", 68, Rarity.COMMON, mage.cards.r.RuneSnag.class)); + cards.add(new SetCardInfo("Runed Halo", 34, Rarity.RARE, mage.cards.r.RunedHalo.class)); + cards.add(new SetCardInfo("Safehold Elite", 220, Rarity.COMMON, mage.cards.s.SafeholdElite.class)); + cards.add(new SetCardInfo("Sanitarium Skeleton", 111, Rarity.COMMON, mage.cards.s.SanitariumSkeleton.class)); + cards.add(new SetCardInfo("Satyr Wayfinder", 180, Rarity.COMMON, mage.cards.s.SatyrWayfinder.class)); + cards.add(new SetCardInfo("Scuzzback Marauders", 221, Rarity.COMMON, mage.cards.s.ScuzzbackMarauders.class)); + cards.add(new SetCardInfo("Seismic Assault", 146, Rarity.RARE, mage.cards.s.SeismicAssault.class)); + cards.add(new SetCardInfo("Seize the Day", 147, Rarity.RARE, mage.cards.s.SeizeTheDay.class)); + cards.add(new SetCardInfo("Shed Weakness", 181, Rarity.COMMON, mage.cards.s.ShedWeakness.class)); + cards.add(new SetCardInfo("Shielding Plax", 222, Rarity.COMMON, mage.cards.s.ShieldingPlax.class)); + cards.add(new SetCardInfo("Shirei, Shizo's Caretaker", 112, Rarity.UNCOMMON, mage.cards.s.ShireiShizosCaretaker.class)); + cards.add(new SetCardInfo("Shriekmaw", 113, Rarity.UNCOMMON, mage.cards.s.Shriekmaw.class)); cards.add(new SetCardInfo("Sigarda, Host of Herons", 206, Rarity.MYTHIC, mage.cards.s.SigardaHostOfHerons.class)); + cards.add(new SetCardInfo("Sigil of the New Dawn", 35, Rarity.UNCOMMON, mage.cards.s.SigilOfTheNewDawn.class)); + cards.add(new SetCardInfo("Skyspear Cavalry", 36, Rarity.COMMON, mage.cards.s.SkyspearCavalry.class)); + cards.add(new SetCardInfo("Skywing Aven", 69, Rarity.COMMON, mage.cards.s.SkywingAven.class)); + cards.add(new SetCardInfo("Sleight of Hand", 70, Rarity.UNCOMMON, mage.cards.s.SleightOfHand.class)); + cards.add(new SetCardInfo("Slippery Bogle", 223, Rarity.UNCOMMON, mage.cards.s.SlipperyBogle.class)); + cards.add(new SetCardInfo("Slum Reaper", 114, Rarity.COMMON, mage.cards.s.SlumReaper.class)); + cards.add(new SetCardInfo("Snake Umbra", 182, Rarity.UNCOMMON, mage.cards.s.SnakeUmbra.class)); cards.add(new SetCardInfo("Snapcaster Mage", 71, Rarity.MYTHIC, mage.cards.s.SnapcasterMage.class)); + cards.add(new SetCardInfo("Songs of the Damned", 115, Rarity.UNCOMMON, mage.cards.s.SongsOfTheDamned.class)); + cards.add(new SetCardInfo("Soul's Fire", 148, Rarity.COMMON, mage.cards.s.SoulsFire.class)); + cards.add(new SetCardInfo("Sovereigns of Lost Alara", 207, Rarity.RARE, mage.cards.s.SovereignsOfLostAlara.class)); + cards.add(new SetCardInfo("Sparkspitter", 149, Rarity.COMMON, mage.cards.s.Sparkspitter.class)); + cards.add(new SetCardInfo("Spider Spawning", 183, Rarity.UNCOMMON, mage.cards.s.SpiderSpawning.class)); + cards.add(new SetCardInfo("Spider Umbra", 184, Rarity.COMMON, mage.cards.s.SpiderUmbra.class)); + cards.add(new SetCardInfo("Spirit Cairn", 37, Rarity.UNCOMMON, mage.cards.s.SpiritCairn.class)); + cards.add(new SetCardInfo("Spoils of the Vault", 116, Rarity.RARE, mage.cards.s.SpoilsOfTheVault.class)); + cards.add(new SetCardInfo("Squee, Goblin Nabob", 150, Rarity.RARE, mage.cards.s.SqueeGoblinNabob.class)); + cards.add(new SetCardInfo("Staunch-Hearted Warrior", 185, Rarity.COMMON, mage.cards.s.StaunchHeartedWarrior.class)); + cards.add(new SetCardInfo("Stingerfling Spider", 186, Rarity.UNCOMMON, mage.cards.s.StingerflingSpider.class)); cards.add(new SetCardInfo("Stirring Wildwood", 251, Rarity.RARE, mage.cards.s.StirringWildwood.class)); + cards.add(new SetCardInfo("Stitched Drake", 72, Rarity.COMMON, mage.cards.s.StitchedDrake.class)); + cards.add(new SetCardInfo("Stitcher's Apprentice", 73, Rarity.COMMON, mage.cards.s.StitchersApprentice.class)); + cards.add(new SetCardInfo("Stream of Consciousness", 74, Rarity.UNCOMMON, mage.cards.s.StreamOfConsciousness.class)); + cards.add(new SetCardInfo("Sublime Archangel", 38, Rarity.RARE, mage.cards.s.SublimeArchangel.class)); + cards.add(new SetCardInfo("Sultai Skullkeeper", 75, Rarity.COMMON, mage.cards.s.SultaiSkullkeeper.class)); + cards.add(new SetCardInfo("Swift Reckoning", 39, Rarity.UNCOMMON, mage.cards.s.SwiftReckoning.class)); + cards.add(new SetCardInfo("Talrand, Sky Summoner", 76, Rarity.RARE, mage.cards.t.TalrandSkySummoner.class)); cards.add(new SetCardInfo("Tarmogoyf", 187, Rarity.MYTHIC, mage.cards.t.Tarmogoyf.class)); cards.add(new SetCardInfo("Tasigur, the Golden Fang", 117, Rarity.RARE, mage.cards.t.TasigurTheGoldenFang.class)); cards.add(new SetCardInfo("Temporal Manipulation", 77, Rarity.MYTHIC, mage.cards.t.TemporalManipulation.class)); + cards.add(new SetCardInfo("Terramorphic Expanse", 252, Rarity.COMMON, mage.cards.t.TerramorphicExpanse.class)); + cards.add(new SetCardInfo("Tethmos High Priest", 40, Rarity.COMMON, mage.cards.t.TethmosHighPriest.class)); + cards.add(new SetCardInfo("Thermo-Alchemist", 151, Rarity.COMMON, mage.cards.t.ThermoAlchemist.class)); + cards.add(new SetCardInfo("Thespian's Stage", 253, Rarity.RARE, mage.cards.t.ThespiansStage.class)); + cards.add(new SetCardInfo("Think Twice", 78, Rarity.COMMON, mage.cards.t.ThinkTwice.class)); cards.add(new SetCardInfo("Through the Breach", 152, Rarity.RARE, mage.cards.t.ThroughTheBreach.class)); + cards.add(new SetCardInfo("Travel Preparations", 188, Rarity.UNCOMMON, mage.cards.t.TravelPreparations.class)); + cards.add(new SetCardInfo("Treasure Cruise", 79, Rarity.COMMON, mage.cards.t.TreasureCruise.class)); + cards.add(new SetCardInfo("Turn to Mist", 224, Rarity.COMMON, mage.cards.t.TurnToMist.class)); + cards.add(new SetCardInfo("Twins of Maurer Estate", 118, Rarity.COMMON, mage.cards.t.TwinsOfMaurerEstate.class)); + cards.add(new SetCardInfo("Ulamog's Crusher", 8, Rarity.COMMON, mage.cards.u.UlamogsCrusher.class)); cards.add(new SetCardInfo("Ulamog, the Infinite Gyre", 7, Rarity.MYTHIC, mage.cards.u.UlamogTheInfiniteGyre.class)); + cards.add(new SetCardInfo("Unburial Rites", 119, Rarity.UNCOMMON, mage.cards.u.UnburialRites.class)); + cards.add(new SetCardInfo("Undying Rage", 153, Rarity.COMMON, mage.cards.u.UndyingRage.class)); + cards.add(new SetCardInfo("Unholy Hunger", 120, Rarity.COMMON, mage.cards.u.UnholyHunger.class)); + cards.add(new SetCardInfo("Unstable Mutation", 80, Rarity.UNCOMMON, mage.cards.u.UnstableMutation.class)); + cards.add(new SetCardInfo("Urban Evolution", 208, Rarity.UNCOMMON, mage.cards.u.UrbanEvolution.class)); cards.add(new SetCardInfo("Urborg, Tomb of Yawgmoth", 254, Rarity.RARE, mage.cards.u.UrborgTombOfYawgmoth.class)); + cards.add(new SetCardInfo("Vengeful Rebirth", 209, Rarity.UNCOMMON, mage.cards.v.VengefulRebirth.class)); cards.add(new SetCardInfo("Vengevine", 189, Rarity.MYTHIC, mage.cards.v.Vengevine.class)); + cards.add(new SetCardInfo("Verdant Eidolon", 190, Rarity.COMMON, mage.cards.v.VerdantEidolon.class)); + cards.add(new SetCardInfo("Vessel of Endless Rest", 235, Rarity.COMMON, mage.cards.v.VesselOfEndlessRest.class)); + cards.add(new SetCardInfo("Vexing Devil", 154, Rarity.RARE, mage.cards.v.VexingDevil.class)); + cards.add(new SetCardInfo("Visions of Beyond", 81, Rarity.RARE, mage.cards.v.VisionsOfBeyond.class)); + cards.add(new SetCardInfo("Walker of the Grove", 191, Rarity.COMMON, mage.cards.w.WalkerOfTheGrove.class)); + cards.add(new SetCardInfo("Wall of Reverence", 41, Rarity.RARE, mage.cards.w.WallOfReverence.class)); + cards.add(new SetCardInfo("Wandering Champion", 42, Rarity.COMMON, mage.cards.w.WanderingChampion.class)); + cards.add(new SetCardInfo("Warleader's Helix", 210, Rarity.UNCOMMON, mage.cards.w.WarleadersHelix.class)); + cards.add(new SetCardInfo("Whirlwind Adept", 82, Rarity.COMMON, mage.cards.w.WhirlwindAdept.class)); + cards.add(new SetCardInfo("Wickerbough Elder", 192, Rarity.COMMON, mage.cards.w.WickerboughElder.class)); + cards.add(new SetCardInfo("Wild Hunger", 193, Rarity.UNCOMMON, mage.cards.w.WildHunger.class)); + cards.add(new SetCardInfo("Wild Mongrel", 194, Rarity.COMMON, mage.cards.w.WildMongrel.class)); + cards.add(new SetCardInfo("Wingsteed Rider", 43, Rarity.COMMON, mage.cards.w.WingsteedRider.class)); + cards.add(new SetCardInfo("Woodfall Primus", 195, Rarity.RARE, mage.cards.w.WoodfallPrimus.class)); + cards.add(new SetCardInfo("Young Pyromancer", 155, Rarity.UNCOMMON, mage.cards.y.YoungPyromancer.class)); } } From 57d5c391fa23d748b8d4df4f92e46359c389b6c1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 22 Nov 2018 16:22:07 +0100 Subject: [PATCH 156/167] * Adroit Hateflayer - Fixed triggered ability only doing damage to opponents instead of all players (#5416). --- Mage.Sets/src/mage/cards/a/AdroitHateflayer.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java b/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java index e51f259f63..dcf0a7f023 100644 --- a/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java +++ b/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java @@ -1,10 +1,9 @@ - package mage.cards.a; import java.util.UUID; import mage.MageInt; import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.effects.common.LoseLifeAllPlayersEffect; import mage.abilities.keyword.MenaceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -18,7 +17,7 @@ import mage.constants.SubType; public final class AdroitHateflayer extends CardImpl { public AdroitHateflayer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}{R}"); this.subtype.add(SubType.NAUTOLAN); this.subtype.add(SubType.SITH); this.power = new MageInt(3); @@ -26,9 +25,9 @@ public final class AdroitHateflayer extends CardImpl { // Menace this.addAbility(new MenaceAbility()); - - // Whenever Adroit Hateflayer attacks, each opponent loses 2 life. - this.addAbility(new AttacksTriggeredAbility(new LoseLifeOpponentsEffect(2), false)); + + // Whenever Adroit Hateflayer attacks, each player loses 2 life. + this.addAbility(new AttacksTriggeredAbility(new LoseLifeAllPlayersEffect(2), false)); } public AdroitHateflayer(final AdroitHateflayer card) { From dbbe92ff0a363eb41a1369353abe57cff1a65300 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 23 Nov 2018 10:59:04 +0100 Subject: [PATCH 157/167] * Outer Rim Slaver - Fixed rule text. Improved target description text (#5416). --- Mage.Sets/src/mage/cards/o/OuterRimSlaver.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/OuterRimSlaver.java b/Mage.Sets/src/mage/cards/o/OuterRimSlaver.java index 98ea2f4b72..438ca1a729 100644 --- a/Mage.Sets/src/mage/cards/o/OuterRimSlaver.java +++ b/Mage.Sets/src/mage/cards/o/OuterRimSlaver.java @@ -1,4 +1,3 @@ - package mage.cards.o; import java.util.UUID; @@ -30,12 +29,13 @@ public final class OuterRimSlaver extends CardImpl { this.toughness = new MageInt(3); // When Outer Rim Slaver enters the battlefield, you may put a bounty counter on target creature. If you do, another target creature fights that creature - Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()), true); - ability.addEffect(new FightTargetsEffect("another target creature fights that creature")); - TargetCreaturePermanent target = new TargetCreaturePermanent(); + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()) + .setText("you may put a bounty counter on target creature"), true); + ability.addEffect(new FightTargetsEffect("If you do, another target creature fights that creature")); + TargetCreaturePermanent target = new TargetCreaturePermanent(new FilterCreaturePermanent("creature to put a bounty counter on it")); target.setTargetTag(1); ability.addTarget(target); - FilterCreaturePermanent filter = new FilterCreaturePermanent(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature to fight that creature that gets the bounty counter"); filter.add(new AnotherTargetPredicate(2)); TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter); target2.setTargetTag(2); From 43ee5e9c43dc6ae9c48d301abdf8792b7b9c79f3 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 23 Nov 2018 12:30:44 +0100 Subject: [PATCH 158/167] * Acklay of the Arena - Fixed triggered ability (fixes #5416). --- Mage.Sets/src/mage/cards/g/GhostQuarter.java | 4 +- .../effects/common/FightTargetsEffect.java | 57 +++++++++++++------ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GhostQuarter.java b/Mage.Sets/src/mage/cards/g/GhostQuarter.java index b84b4a3ba4..66a20c6860 100644 --- a/Mage.Sets/src/mage/cards/g/GhostQuarter.java +++ b/Mage.Sets/src/mage/cards/g/GhostQuarter.java @@ -1,4 +1,3 @@ - package mage.cards.g; import java.util.UUID; @@ -16,7 +15,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.filter.common.FilterBasicLandCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -30,7 +28,7 @@ import mage.target.common.TargetLandPermanent; public final class GhostQuarter extends CardImpl { public GhostQuarter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // {T}: Add {C}. this.addAbility(new ColorlessManaAbility()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/FightTargetsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FightTargetsEffect.java index c0fd2f1ca5..db8b80f874 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/FightTargetsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/FightTargetsEffect.java @@ -1,6 +1,6 @@ - package mage.abilities.effects.common; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; @@ -32,35 +32,58 @@ public class FightTargetsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Card card = game.getCard(source.getSourceId()); if (card != null) { - // only if both targets are legal the effect will be applied - if (source.getTargets().get(0).isLegal(source, game) && source.getTargets().get(1).isLegal(source, game)) { - Permanent creature1 = game.getPermanent(source.getTargets().get(0).getFirstTarget()); - Permanent creature2 = game.getPermanent(source.getTargets().get(1).getFirstTarget()); - // 20110930 - 701.10 - if (creature1 != null && creature2 != null) { - if (creature1.isCreature() && creature2.isCreature()) { - return creature1.fight(creature2, source, game); - } + UUID target1Id = null; + UUID target2Id = null; + // first target is in target pointer, second target is a normal target + if (source.getTargets().size() < 2) { + if (!source.getTargets().get(0).isLegal(source, game)) { + return false; + } + target1Id = getTargetPointer().getFirst(game, source); + target2Id = source.getTargets().getFirstTarget(); + if (target1Id == target2Id) { + return false; + } + // two normal targets available, only if both targets are legal the effect will be applied + } else if (source.getTargets().get(0).isLegal(source, game) && source.getTargets().get(1).isLegal(source, game)) { + target1Id = source.getTargets().get(0).getFirstTarget(); + target2Id = source.getTargets().get(1).getFirstTarget(); + } + Permanent creature1 = game.getPermanent(target1Id); + Permanent creature2 = game.getPermanent(target2Id); + // 20110930 - 701.10 + if (creature1 != null && creature2 != null) { + if (creature1.isCreature() && creature2.isCreature()) { + return creature1.fight(creature2, source, game); } } - if (!game.isSimulation()) { - game.informPlayers(card.getName() + " has been fizzled."); - } + } + if (!game.isSimulation()) { + game.informPlayers(card.getName() + " has been fizzled."); } return false; } @Override - public FightTargetsEffect copy() { + public FightTargetsEffect + copy() { return new FightTargetsEffect(this); + } @Override - public String getText(Mode mode) { - if (staticText != null && !staticText.isEmpty()) { + public String + getText(Mode mode + ) { + if (staticText + != null && !staticText + .isEmpty()) { return staticText; + } - return "Target " + mode.getTargets().get(0).getTargetName() + " fights another target " + mode.getTargets().get(1).getTargetName(); + return "Target " + mode + .getTargets().get(0).getTargetName() + " fights another target " + mode + .getTargets().get(1).getTargetName(); } } From 2e17cb334e445b6f2dd2df33338a925036af6c3c Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Fri, 23 Nov 2018 11:36:29 -0600 Subject: [PATCH 159/167] - Fixed #5100. Added a replacement effect for skipping the combat phase. --- Mage.Sets/src/mage/cards/b/BlindingAngel.java | 22 ++++---- Mage.Sets/src/mage/cards/e/EmptyCityRuse.java | 10 ++-- Mage.Sets/src/mage/cards/f/FalsePeace.java | 14 ++--- .../src/mage/cards/m/MomentOfSilence.java | 14 ++--- .../src/mage/cards/r/RevenantPatriarch.java | 14 ++--- .../src/mage/cards/s/StonehornDignitary.java | 18 +++--- .../effects/common/SkipCombatStepEffect.java | 55 +++++++++++++++++++ 7 files changed, 102 insertions(+), 45 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/SkipCombatStepEffect.java diff --git a/Mage.Sets/src/mage/cards/b/BlindingAngel.java b/Mage.Sets/src/mage/cards/b/BlindingAngel.java index c75b26c07e..f7f25c29ab 100644 --- a/Mage.Sets/src/mage/cards/b/BlindingAngel.java +++ b/Mage.Sets/src/mage/cards/b/BlindingAngel.java @@ -1,14 +1,14 @@ - package mage.cards.b; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; /** @@ -16,26 +16,28 @@ import mage.constants.SubType; * @author Plopman */ public final class BlindingAngel extends CardImpl { - + public BlindingAngel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); this.subtype.add(SubType.ANGEL); - + this.power = new MageInt(2); this.toughness = new MageInt(4); // Flying this.addAbility(FlyingAbility.getInstance()); - // Whenever Blinding Angel deals combat damage to a player, that player skips their next combat phase. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SkipNextCombatEffect(), false, true)); - } + // Whenever Blinding Angel deals combat damage to a player, that player skips their next combat phase. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("that player skips their next combat phase."), false, true)); + + } + public BlindingAngel(final BlindingAngel card) { super(card); } - + @Override public BlindingAngel copy() { return new BlindingAngel(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/e/EmptyCityRuse.java b/Mage.Sets/src/mage/cards/e/EmptyCityRuse.java index 020899fc0e..8e1ff3e417 100644 --- a/Mage.Sets/src/mage/cards/e/EmptyCityRuse.java +++ b/Mage.Sets/src/mage/cards/e/EmptyCityRuse.java @@ -1,11 +1,11 @@ - package mage.cards.e; import java.util.UUID; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.target.common.TargetOpponent; /** @@ -15,10 +15,10 @@ import mage.target.common.TargetOpponent; public final class EmptyCityRuse extends CardImpl { public EmptyCityRuse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}"); // Target opponent skips all combat phases of their next turn. - this.getSpellAbility().addEffect(new SkipNextCombatEffect()); + this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.UntilYourNextTurn).setText("Target opponent skips all combat phases of their next turn.")); this.getSpellAbility().addTarget(new TargetOpponent()); } @@ -30,4 +30,4 @@ public final class EmptyCityRuse extends CardImpl { public EmptyCityRuse copy() { return new EmptyCityRuse(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/FalsePeace.java b/Mage.Sets/src/mage/cards/f/FalsePeace.java index 026dae7c19..55bfe14023 100644 --- a/Mage.Sets/src/mage/cards/f/FalsePeace.java +++ b/Mage.Sets/src/mage/cards/f/FalsePeace.java @@ -1,11 +1,11 @@ - package mage.cards.f; import java.util.UUID; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.target.TargetPlayer; /** @@ -13,19 +13,19 @@ import mage.target.TargetPlayer; * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com) */ public final class FalsePeace extends CardImpl { - + public FalsePeace(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}"); // Target player skips all combat phases of their next turn. - this.getSpellAbility().addEffect(new SkipNextCombatEffect()); + this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.UntilYourNextTurn).setText("Target player skips all combat phases of their next turn.")); this.getSpellAbility().addTarget(new TargetPlayer()); } - + public FalsePeace(final FalsePeace card) { super(card); } - + @Override public FalsePeace copy() { return new FalsePeace(this); diff --git a/Mage.Sets/src/mage/cards/m/MomentOfSilence.java b/Mage.Sets/src/mage/cards/m/MomentOfSilence.java index 50e275a7ed..6607ae3528 100644 --- a/Mage.Sets/src/mage/cards/m/MomentOfSilence.java +++ b/Mage.Sets/src/mage/cards/m/MomentOfSilence.java @@ -1,11 +1,11 @@ - package mage.cards.m; import java.util.UUID; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.target.TargetPlayer; /** @@ -13,19 +13,19 @@ import mage.target.TargetPlayer; * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com) */ public final class MomentOfSilence extends CardImpl { - + public MomentOfSilence(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Target player skips their next combat phase this turn. - this.getSpellAbility().addEffect(new SkipNextCombatEffect()); + this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.EndOfTurn).setText("Target player skips their next combat this turn")); this.getSpellAbility().addTarget(new TargetPlayer()); } - + public MomentOfSilence(final MomentOfSilence card) { super(card); } - + @Override public MomentOfSilence copy() { return new MomentOfSilence(this); diff --git a/Mage.Sets/src/mage/cards/r/RevenantPatriarch.java b/Mage.Sets/src/mage/cards/r/RevenantPatriarch.java index 50b1fd07e8..e770b5d439 100644 --- a/Mage.Sets/src/mage/cards/r/RevenantPatriarch.java +++ b/Mage.Sets/src/mage/cards/r/RevenantPatriarch.java @@ -1,4 +1,3 @@ - package mage.cards.r; import java.util.UUID; @@ -8,12 +7,13 @@ import mage.abilities.common.CantBlockAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.ColoredManaSymbol; +import mage.constants.Duration; import mage.target.TargetPlayer; import mage.watchers.common.ManaSpentToCastWatcher; @@ -22,26 +22,26 @@ import mage.watchers.common.ManaSpentToCastWatcher; * @author ilcartographer */ public final class RevenantPatriarch extends CardImpl { - + public RevenantPatriarch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(4); this.toughness = new MageInt(3); // When Revenant Patriarch enters the battlefield, if {W} was spent to cast it, target player skips their next combat phase. - TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new SkipNextCombatEffect(), false); + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("target player skips their next combat phase."), false); ability.addTarget(new TargetPlayer()); this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new ManaWasSpentCondition(ColoredManaSymbol.W), "if {W} was spent to cast it, target player skips their next combat phase."), new ManaSpentToCastWatcher()); // Revenant Patriarch can't block. this.addAbility(new CantBlockAbility()); } - + public RevenantPatriarch(final RevenantPatriarch card) { super(card); } - + @Override public RevenantPatriarch copy() { return new RevenantPatriarch(this); diff --git a/Mage.Sets/src/mage/cards/s/StonehornDignitary.java b/Mage.Sets/src/mage/cards/s/StonehornDignitary.java index 3f92110a13..0443f4f16d 100644 --- a/Mage.Sets/src/mage/cards/s/StonehornDignitary.java +++ b/Mage.Sets/src/mage/cards/s/StonehornDignitary.java @@ -1,14 +1,14 @@ - package mage.cards.s; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; import mage.target.common.TargetOpponent; @@ -17,27 +17,27 @@ import mage.target.common.TargetOpponent; * @author nantuko */ public final class StonehornDignitary extends CardImpl { - + public StonehornDignitary(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.RHINO); this.subtype.add(SubType.SOLDIER); - + this.power = new MageInt(1); this.toughness = new MageInt(4); // When Stonehorn Dignitary enters the battlefield, target opponent skips their next combat phase. - Ability ability = new EntersBattlefieldTriggeredAbility(new SkipNextCombatEffect()); + Ability ability = new EntersBattlefieldTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("target opponent skips their next combat phase.")); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } - + public StonehornDignitary(final StonehornDignitary card) { super(card); } - + @Override public StonehornDignitary copy() { return new StonehornDignitary(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SkipCombatStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SkipCombatStepEffect.java new file mode 100644 index 0000000000..4d72fe19fd --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/SkipCombatStepEffect.java @@ -0,0 +1,55 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author jeffwadsworth + */ + +public class SkipCombatStepEffect extends ReplacementEffectImpl { + + public SkipCombatStepEffect(Duration duration) { + super(duration, Outcome.Detriment); + staticText = "that player skips their next combat phase"; + } + + public SkipCombatStepEffect(final SkipCombatStepEffect effect) { + super(effect); + } + + @Override + public SkipCombatStepEffect copy() { + return new SkipCombatStepEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.COMBAT_PHASE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getPlayerId().equals(targetPointer.getFirst(game, source)); + } +} From ed69c0449014e37f4ab2496ed665b0ca8b0e5f0d Mon Sep 17 00:00:00 2001 From: Ingmar Goudt Date: Fri, 23 Nov 2018 20:05:30 +0100 Subject: [PATCH 160/167] fix for #5417 --- Mage.Sets/src/mage/cards/i/Icequake.java | 14 ++++++----- .../test/cards/conditional/IcequakeTest.java | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/conditional/IcequakeTest.java diff --git a/Mage.Sets/src/mage/cards/i/Icequake.java b/Mage.Sets/src/mage/cards/i/Icequake.java index cad1b47cd1..70399b40e7 100644 --- a/Mage.Sets/src/mage/cards/i/Icequake.java +++ b/Mage.Sets/src/mage/cards/i/Icequake.java @@ -59,14 +59,16 @@ class IcequakeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null && controller != null) { - permanent.destroy(source.getSourceId(), game, false); - if (permanent.isSnow()) { - controller.damage(1, source.getSourceId(), game, false, true); + if (permanent != null) { + Player controller = game.getPlayer(permanent.getControllerId()); + if(controller != null) { + permanent.destroy(source.getSourceId(), game, false); + if (permanent.isSnow()) { + controller.damage(1, source.getSourceId(), game, false, true); + } + return true; } - return true; } return false; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/IcequakeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/IcequakeTest.java new file mode 100644 index 0000000000..f3db7d6379 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/IcequakeTest.java @@ -0,0 +1,25 @@ +package org.mage.test.cards.conditional; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class IcequakeTest extends CardTestPlayerBase { + + @Test + public void testIcequakeOnSnowLand(){ + + addCard(Zone.BATTLEFIELD, playerB, "Snow-Covered Plains"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp",10); + addCard(Zone.HAND, playerA, "Icequake"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN,playerA, "Icequake", "Snow-Covered Plains"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 19); + } +} From 25e7b53268ec320c09660e8bfd8afcdcd5ce6ebf Mon Sep 17 00:00:00 2001 From: Ingmar Goudt Date: Sat, 24 Nov 2018 23:50:05 +0100 Subject: [PATCH 161/167] small performance update for ClassScanner --- Mage/src/main/java/mage/util/ClassScanner.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mage/src/main/java/mage/util/ClassScanner.java b/Mage/src/main/java/mage/util/ClassScanner.java index 46609ea4ba..47972fe400 100644 --- a/Mage/src/main/java/mage/util/ClassScanner.java +++ b/Mage/src/main/java/mage/util/ClassScanner.java @@ -33,8 +33,8 @@ public final class ClassScanner { if(classLoader == null) classLoader = Thread.currentThread().getContextClassLoader(); assert classLoader != null; - HashMap dirs = new HashMap<>(); - TreeSet jars = new TreeSet<>(); + Map dirs = new HashMap<>(); + Set jars = new TreeSet<>(); for (String packageName : packages) { String path = packageName.replace('.', '/'); Enumeration resources = classLoader.getResources(path); @@ -51,8 +51,8 @@ public final class ClassScanner { } } - for (String filePath : dirs.keySet()) { - cards.addAll(findClasses(classLoader, new File(filePath), dirs.get(filePath), type)); + for (Map.Entry dir : dirs.entrySet()) { + cards.addAll(findClasses(classLoader, new File(dir.getKey()), dir.getValue(), type)); } for (String filePath : jars) { @@ -66,7 +66,7 @@ public final class ClassScanner { private static List findClasses(ClassLoader classLoader, File directory, String packageName, Class type) { List cards = new ArrayList<>(); - if (!directory.exists()) return cards; + if (directory == null || !directory.exists()) return cards; for (File file : directory.listFiles()) { if (file.getName().endsWith(".class")) { From 2144ae75a4cabb230353d68ea597cd9b68210c44 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 10:08:30 -0600 Subject: [PATCH 162/167] - Added Archery Training and Fend Off. --- .../src/mage/cards/a/ArcheryTraining.java | 67 +++++++++++++++++++ Mage.Sets/src/mage/cards/f/FendOff.java | 41 ++++++++++++ Mage.Sets/src/mage/sets/UrzasDestiny.java | 2 + 3 files changed, 110 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArcheryTraining.java create mode 100644 Mage.Sets/src/mage/cards/f/FendOff.java diff --git a/Mage.Sets/src/mage/cards/a/ArcheryTraining.java b/Mage.Sets/src/mage/cards/a/ArcheryTraining.java new file mode 100644 index 0000000000..f70caaa22c --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArcheryTraining.java @@ -0,0 +1,67 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetAttackingOrBlockingCreature; + +/** + * + * @author jeffwadsworth + */ +public final class ArcheryTraining extends CardImpl { + + private static final String rule = "This creature deals X damage to target attacking or blocking creature, where X is the number of arrow counters on {this}."; + + public ArcheryTraining(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of your upkeep, you may put an arrow counter on Archery Training. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.ARROW.createInstance(), true), TargetController.YOU, true)); + + // Enchanted creature has "{tap}: This creature deals X damage to target attacking or blocking creature, where X is the number of arrow counters on Archery Training." + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new CountersSourceCount(CounterType.ARROW)).setText(rule), new TapSourceCost()); + gainedAbility.addTarget(new TargetAttackingOrBlockingCreature()); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA))); + + } + + public ArcheryTraining(final ArcheryTraining card) { + super(card); + } + + @Override + public ArcheryTraining copy() { + return new ArcheryTraining(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FendOff.java b/Mage.Sets/src/mage/cards/f/FendOff.java new file mode 100644 index 0000000000..045d166fe7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FendOff.java @@ -0,0 +1,41 @@ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.PreventDamageByTargetEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public final class FendOff extends CardImpl { + + private static final String rule = "Prevent all combat damage that would be dealt by target creature this turn."; + + public FendOff(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Prevent all combat damage that would be dealt by target creature this turn. + this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true).setText(rule)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public FendOff(final FendOff card) { + super(card); + } + + @Override + public FendOff copy() { + return new FendOff(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index 810b12ccff..2590ab67e5 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -32,6 +32,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Aether Sting", 76, Rarity.UNCOMMON, mage.cards.a.AetherSting.class)); cards.add(new SetCardInfo("Ancient Silverback", 101, Rarity.RARE, mage.cards.a.AncientSilverback.class)); cards.add(new SetCardInfo("Apprentice Necromancer", 51, Rarity.RARE, mage.cards.a.ApprenticeNecromancer.class)); + cards.add(new SetCardInfo("Archery Training", 2, Rarity.UNCOMMON, mage.cards.a.ArcheryTraining.class)); cards.add(new SetCardInfo("Attrition", 52, Rarity.RARE, mage.cards.a.Attrition.class)); cards.add(new SetCardInfo("Aura Thief", 26, Rarity.RARE, mage.cards.a.AuraThief.class)); cards.add(new SetCardInfo("Blizzard Elemental", 27, Rarity.RARE, mage.cards.b.BlizzardElemental.class)); @@ -63,6 +64,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Eradicate", 60, Rarity.UNCOMMON, mage.cards.e.Eradicate.class)); cards.add(new SetCardInfo("Extruder", 130, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("False Prophet", 6, Rarity.RARE, mage.cards.f.FalseProphet.class)); + cards.add(new SetCardInfo("Fend Off", 7, Rarity.COMMON, mage.cards.f.FendOff.class)); cards.add(new SetCardInfo("Festering Wound", 61, Rarity.UNCOMMON, mage.cards.f.FesteringWound.class)); cards.add(new SetCardInfo("Field Surgeon", 8, Rarity.COMMON, mage.cards.f.FieldSurgeon.class)); cards.add(new SetCardInfo("Flame Jet", 81, Rarity.COMMON, mage.cards.f.FlameJet.class)); From 9c0162caad06038485c74cadcd1850ff406f6cc5 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 10:11:50 -0600 Subject: [PATCH 163/167] - Added "ARROW" counter. --- Mage/src/main/java/mage/counters/CounterType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index fd2eb77912..a5ce8b6a60 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -9,6 +9,7 @@ public enum CounterType { AGE("age"), AIM("aim"), + ARROW("arrow"), ARROWHEAD("arrowhead"), AWAKENING("awakening"), BLAZE("blaze"), From ea4c202a40f89ea9911c5b8e4b00a410092bb315 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 10:51:27 -0600 Subject: [PATCH 164/167] - Added Fatigue and Disappear. --- Mage.Sets/src/mage/cards/d/Disappear.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/cards/f/Fatigue.java | 36 ++++++++ .../common/SkipNextDrawStepTargetEffect.java | 55 ++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/Disappear.java create mode 100644 Mage.Sets/src/mage/cards/f/Fatigue.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/d/Disappear.java b/Mage.Sets/src/mage/cards/d/Disappear.java new file mode 100644 index 0000000000..43b6fa78a8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Disappear.java @@ -0,0 +1,87 @@ +package mage.cards.d; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public final class Disappear extends CardImpl { + + public Disappear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // {U}: Return enchanted creature and Disappear to their owners' hands. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DisappearEffect(), new ManaCostsImpl("{U}"))); + + } + + public Disappear(final Disappear card) { + super(card); + } + + @Override + public Disappear copy() { + return new Disappear(this); + } +} + +class DisappearEffect extends OneShotEffect { + + public DisappearEffect() { + super(Outcome.ReturnToHand); + staticText = "Return enchanted creature and {this} to their owners' hands"; + } + + public DisappearEffect(final DisappearEffect effect) { + super(effect); + } + + @Override + public DisappearEffect copy() { + return new DisappearEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent aura = (Permanent) game.getPermanentOrLKIBattlefield(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null + && aura != null + && aura.getAttachedTo() != null) { + Permanent enchantedCreature = game.getPermanent(aura.getAttachedTo()); + controller.moveCards(aura, Zone.HAND, source, game); + if (enchantedCreature != null) { + controller.moveCards(enchantedCreature, Zone.HAND, source, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/f/Fatigue.java b/Mage.Sets/src/mage/cards/f/Fatigue.java new file mode 100644 index 0000000000..8f3ae9784b --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/Fatigue.java @@ -0,0 +1,36 @@ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.effects.common.SkipNextDrawStepTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author jeffwadsworth + */ +public final class Fatigue extends CardImpl { + + private static final String rule = "Target player skips his or her next draw step."; + + public Fatigue(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}"); + + + // Target player skips his or her next draw step. + this.getSpellAbility().addEffect(new SkipNextDrawStepTargetEffect().setText(rule)); + this.getSpellAbility().addTarget(new TargetPlayer()); + + } + + public Fatigue(final Fatigue card) { + super(card); + } + + @Override + public Fatigue copy() { + return new Fatigue(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepTargetEffect.java new file mode 100644 index 0000000000..2f1ba7d187 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepTargetEffect.java @@ -0,0 +1,55 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author jeffwadsworth + */ + +public class SkipNextDrawStepTargetEffect extends ReplacementEffectImpl { + + public SkipNextDrawStepTargetEffect() { + super(Duration.OneUse, Outcome.Detriment); + staticText = "Target player skips his or her next draw step"; + } + + public SkipNextDrawStepTargetEffect(final SkipNextDrawStepTargetEffect effect) { + super(effect); + } + + @Override + public SkipNextDrawStepTargetEffect copy() { + return new SkipNextDrawStepTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DRAW_STEP; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getPlayerId().equals(source.getFirstTarget()); + } +} \ No newline at end of file From 2e9879616c0c9e2282758509eeab78aa72c2d2dd Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 10:52:16 -0600 Subject: [PATCH 165/167] - Updated Urza's Destiny set. --- Mage.Sets/src/mage/sets/UrzasDestiny.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index 2590ab67e5..d5b344ce21 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -54,6 +54,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Colos Yearling", 79, Rarity.COMMON, mage.cards.c.ColosYearling.class)); cards.add(new SetCardInfo("Compost", 102, Rarity.UNCOMMON, mage.cards.c.Compost.class)); cards.add(new SetCardInfo("Covetous Dragon", 80, Rarity.RARE, mage.cards.c.CovetousDragon.class)); + cards.add(new SetCardInfo("Disappear", 30, Rarity.UNCOMMON, mage.cards.d.Disappear.class)); cards.add(new SetCardInfo("Disease Carriers", 57, Rarity.COMMON, mage.cards.d.DiseaseCarriers.class)); cards.add(new SetCardInfo("Donate", 31, Rarity.RARE, mage.cards.d.Donate.class)); cards.add(new SetCardInfo("Dying Wail", 58, Rarity.COMMON, mage.cards.d.DyingWail.class)); @@ -64,6 +65,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Eradicate", 60, Rarity.UNCOMMON, mage.cards.e.Eradicate.class)); cards.add(new SetCardInfo("Extruder", 130, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("False Prophet", 6, Rarity.RARE, mage.cards.f.FalseProphet.class)); + cards.add(new SetCardInfo("Fatigue", 32, Rarity.COMMON, mage.cards.f.Fatigue.class)); cards.add(new SetCardInfo("Fend Off", 7, Rarity.COMMON, mage.cards.f.FendOff.class)); cards.add(new SetCardInfo("Festering Wound", 61, Rarity.UNCOMMON, mage.cards.f.FesteringWound.class)); cards.add(new SetCardInfo("Field Surgeon", 8, Rarity.COMMON, mage.cards.f.FieldSurgeon.class)); From 4f0725586b5d7ffbb7edb2a4fbc2cfc5eed4c104 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 11:40:10 -0600 Subject: [PATCH 166/167] - Urza's Destiny 100%. Added Private Research, Lurking Jackals, Incendiary. --- Mage.Sets/src/mage/cards/i/Incendiary.java | 65 +++++++++ .../src/mage/cards/l/LurkingJackals.java | 123 ++++++++++++++++++ .../src/mage/cards/p/PrivateResearch.java | 60 +++++++++ Mage.Sets/src/mage/sets/UrzasDestiny.java | 3 + 4 files changed, 251 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/Incendiary.java create mode 100644 Mage.Sets/src/mage/cards/l/LurkingJackals.java create mode 100644 Mage.Sets/src/mage/cards/p/PrivateResearch.java diff --git a/Mage.Sets/src/mage/cards/i/Incendiary.java b/Mage.Sets/src/mage/cards/i/Incendiary.java new file mode 100644 index 0000000000..f5987a4793 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/Incendiary.java @@ -0,0 +1,65 @@ +package mage.cards.i; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author jeffwadsworth + */ +public final class Incendiary extends CardImpl { + + private static final String rule = "{this} deals X damage to any target, where X is the number of fuse counters on {this}."; + + public Incendiary(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of your upkeep, you may put a fuse counter on Incendiary. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.FUSE.createInstance(), true), TargetController.YOU, true)); + + // When enchanted creature dies, Incendiary deals X damage to any target, where X is the number of fuse counters on Incendiary. + Effect effect = new DamageTargetEffect(new CountersSourceCount(CounterType.FUSE)).setText(rule); + Ability ability2 = new DiesAttachedTriggeredAbility(effect, "enchanted creature"); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability2); + + } + + public Incendiary(final Incendiary card) { + super(card); + } + + @Override + public Incendiary copy() { + return new Incendiary(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LurkingJackals.java b/Mage.Sets/src/mage/cards/l/LurkingJackals.java new file mode 100644 index 0000000000..2ff584e5a7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LurkingJackals.java @@ -0,0 +1,123 @@ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +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.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class LurkingJackals extends CardImpl { + + public LurkingJackals(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}"); + + // When an opponent has 10 or less life, if Lurking Jackals is an enchantment, it becomes a 3/2 Hound creature. + this.addAbility(new LurkingJackalsStateTriggeredAbility()); + } + + public LurkingJackals(final LurkingJackals card) { + super(card); + } + + @Override + public LurkingJackals copy() { + return new LurkingJackals(this); + } +} + +class LurkingJackalsStateTriggeredAbility extends StateTriggeredAbility { + + public LurkingJackalsStateTriggeredAbility() { + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new LurkingJackalsToken(), "", Duration.Custom, true, false)); + } + + public LurkingJackalsStateTriggeredAbility(final LurkingJackalsStateTriggeredAbility ability) { + super(ability); + } + + @Override + public LurkingJackalsStateTriggeredAbility copy() { + return new LurkingJackalsStateTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (game.getOpponents(getControllerId()).stream().anyMatch((playerId) -> (game.getPlayer(playerId).getLife() <= 10))) { + return true; + } + return false; + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + } + + @Override + public boolean canTrigger(Game game) { + //20100716 - 603.8 + Boolean triggered = (Boolean) game.getState().getValue(getSourceId().toString() + "triggered"); + if (triggered == null) { + triggered = Boolean.FALSE; + } + return !triggered; + } + + @Override + public void trigger(Game game, UUID controllerId) { + //20100716 - 603.8 + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE); + super.trigger(game, controllerId); + } + + @Override + public boolean resolve(Game game) { + //20100716 - 603.8 + boolean result = super.resolve(game); + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + return result; + } + + @Override + public void counter(Game game) { + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + } + + @Override + public String getRule() { + return new StringBuilder("When an opponent has 10 or less life, if {this} is an enchantment, ").append(super.getRule()).toString(); + } + +} + +class LurkingJackalsToken extends TokenImpl { + + public LurkingJackalsToken() { + super("Hound", "3/2 Hound creature"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.HOUND); + power = new MageInt(3); + toughness = new MageInt(2); + } + + public LurkingJackalsToken(final LurkingJackalsToken token) { + super(token); + } + + @Override + public LurkingJackalsToken copy() { + return new LurkingJackalsToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PrivateResearch.java b/Mage.Sets/src/mage/cards/p/PrivateResearch.java new file mode 100644 index 0000000000..bef10ca1c2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrivateResearch.java @@ -0,0 +1,60 @@ +package mage.cards.p; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; + +/** + * + * @author jeffwadsworth + */ +public final class PrivateResearch extends CardImpl { + + private static final String rule = "draw a card for each page counter on {this}."; + + public PrivateResearch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of your upkeep, you may put a page counter on Private Research. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.PAGE.createInstance(), true), TargetController.YOU, true)); + + // When enchanted creature dies, draw a card for each page counter on Private Research. + this.addAbility(new DiesAttachedTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.PAGE)).setText(rule), "enchanted creature")); + + } + + public PrivateResearch(final PrivateResearch card) { + super(card); + } + + @Override + public PrivateResearch copy() { + return new PrivateResearch(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index d5b344ce21..aae8ca309c 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -85,6 +85,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Hunting Moa", 109, Rarity.UNCOMMON, mage.cards.h.HuntingMoa.class)); cards.add(new SetCardInfo("Illuminated Wings", 34, Rarity.COMMON, mage.cards.i.IlluminatedWings.class)); cards.add(new SetCardInfo("Impatience", 88, Rarity.RARE, mage.cards.i.Impatience.class)); + cards.add(new SetCardInfo("Incendiary", 89, Rarity.UNCOMMON, mage.cards.i.Incendiary.class)); cards.add(new SetCardInfo("Iridescent Drake", 35, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); cards.add(new SetCardInfo("Ivy Seer", 110, Rarity.UNCOMMON, mage.cards.i.IvySeer.class)); cards.add(new SetCardInfo("Jasmine Seer", 10, Rarity.UNCOMMON, mage.cards.j.JasmineSeer.class)); @@ -93,6 +94,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Keldon Vandals", 91, Rarity.COMMON, mage.cards.k.KeldonVandals.class)); cards.add(new SetCardInfo("Kingfisher", 36, Rarity.COMMON, mage.cards.k.Kingfisher.class)); cards.add(new SetCardInfo("Landslide", 92, Rarity.UNCOMMON, mage.cards.l.Landslide.class)); + cards.add(new SetCardInfo("Lurking Jackals", 62, Rarity.UNCOMMON, mage.cards.l.LurkingJackals.class)); cards.add(new SetCardInfo("Magnify", 111, Rarity.COMMON, mage.cards.m.Magnify.class)); cards.add(new SetCardInfo("Mantis Engine", 133, Rarity.UNCOMMON, mage.cards.m.MantisEngine.class)); cards.add(new SetCardInfo("Marker Beetles", 112, Rarity.COMMON, mage.cards.m.MarkerBeetles.class)); @@ -116,6 +118,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Plated Spider", 116, Rarity.COMMON, mage.cards.p.PlatedSpider.class)); cards.add(new SetCardInfo("Plow Under", 117, Rarity.RARE, mage.cards.p.PlowUnder.class)); cards.add(new SetCardInfo("Powder Keg", 136, Rarity.RARE, mage.cards.p.PowderKeg.class)); + cards.add(new SetCardInfo("Private Research", 41, Rarity.UNCOMMON, mage.cards.p.PrivateResearch.class)); cards.add(new SetCardInfo("Quash", 42, Rarity.UNCOMMON, mage.cards.q.Quash.class)); cards.add(new SetCardInfo("Rapid Decay", 67, Rarity.RARE, mage.cards.r.RapidDecay.class)); cards.add(new SetCardInfo("Ravenous Rats", 68, Rarity.COMMON, mage.cards.r.RavenousRats.class)); From a01891f11e3578ba05c273f88e5e40a03d3c9866 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 19:11:12 -0600 Subject: [PATCH 167/167] - added some null checks. --- Mage.Sets/src/mage/cards/h/HiddenPredators.java | 5 ++++- Mage.Sets/src/mage/cards/l/LurkingJackals.java | 13 ++++++++++--- Mage.Sets/src/mage/cards/o/OpalAvenger.java | 10 ++++++++-- Mage.Sets/src/mage/cards/v/VeiledCrocodile.java | 5 ++++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/h/HiddenPredators.java b/Mage.Sets/src/mage/cards/h/HiddenPredators.java index f5ff50d09b..88f532926e 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenPredators.java +++ b/Mage.Sets/src/mage/cards/h/HiddenPredators.java @@ -71,7 +71,10 @@ class HiddenPredatorsStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkInterveningIfClause(Game game) { - return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + if (getSourcePermanentIfItStillExists(game) != null) { + return getSourcePermanentIfItStillExists(game).isEnchantment(); + } + return false; } @Override diff --git a/Mage.Sets/src/mage/cards/l/LurkingJackals.java b/Mage.Sets/src/mage/cards/l/LurkingJackals.java index 2ff584e5a7..4822bb2c2d 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingJackals.java +++ b/Mage.Sets/src/mage/cards/l/LurkingJackals.java @@ -54,15 +54,22 @@ class LurkingJackalsStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getOpponents(getControllerId()).stream().anyMatch((playerId) -> (game.getPlayer(playerId).getLife() <= 10))) { - return true; + if (game.getOpponents(getControllerId()) != null) { + for (UUID opponentId : game.getOpponents(getControllerId())) { + if (game.getPlayer(opponentId).getLife() <= 10) { + return true; + } + } } return false; } @Override public boolean checkInterveningIfClause(Game game) { - return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + if (getSourcePermanentIfItStillExists(game) != null) { + return getSourcePermanentIfItStillExists(game).isEnchantment(); + } + return false; } @Override diff --git a/Mage.Sets/src/mage/cards/o/OpalAvenger.java b/Mage.Sets/src/mage/cards/o/OpalAvenger.java index 5586cbedf6..cc28e07424 100644 --- a/Mage.Sets/src/mage/cards/o/OpalAvenger.java +++ b/Mage.Sets/src/mage/cards/o/OpalAvenger.java @@ -54,12 +54,18 @@ class OpalAvengerStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getState().getPlayer(getControllerId()).getLife() <= 10; + if (game.getState().getPlayer(getControllerId()) != null) { + return game.getState().getPlayer(getControllerId()).getLife() <= 10; + } + return false; } @Override public boolean checkInterveningIfClause(Game game) { - return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + if (getSourcePermanentIfItStillExists(game) != null) { + return getSourcePermanentIfItStillExists(game).isEnchantment(); + } + return false; } @Override diff --git a/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java index c3790e5c73..860795598a 100644 --- a/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java +++ b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java @@ -67,7 +67,10 @@ class VeiledCrocodileStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkInterveningIfClause(Game game) { - return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + if (getSourcePermanentIfItStillExists(game) != null) { + return getSourcePermanentIfItStillExists(game).isEnchantment(); + } + return false; } @Override