diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java index 64b23245c84..7c4dbf24804 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardRenderer.java @@ -14,7 +14,6 @@ import java.awt.Paint; import java.awt.Polygon; import java.awt.image.BufferedImage; import java.util.ArrayList; - import mage.client.dialog.PreferencesDialog; import mage.constants.AbilityType; import mage.constants.CardType; @@ -171,11 +170,12 @@ public abstract class CardRenderer { } /** - * How far does a card have to be spaced down from - * a rendered card to show it's entire name line? - * This function is a bit of a hack, as different card faces need - * slightly different spacing, but we need it in a static context - * so that spacing is consistent in GY / deck views etc. + * How far does a card have to be spaced down from a rendered card to show + * it's entire name line? This function is a bit of a hack, as different + * card faces need slightly different spacing, but we need it in a static + * context so that spacing is consistent in GY / deck views etc. + * + * @param cardWidth * @return */ public static int getCardTopHeight(int cardWidth) { @@ -186,7 +186,7 @@ public abstract class CardRenderer { BOX_HEIGHT_MIN, BOX_HEIGHT_FRAC * cardWidth * 1.4f); int borderWidth = getBorderWidth(cardWidth); - return 2*borderWidth + boxHeight; + return 2 * borderWidth + boxHeight; } // The Draw Method 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 628ecd66c0e..94ca7ef8304 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 @@ -19,14 +19,16 @@ import java.util.regex.Pattern; /** * @author stravant@gmail.com - * + * * Various static utilities for use in the card renderer */ public class CardRendererUtils { + /** - * Convert an abstract image, whose underlying implementation may or may - * not be a BufferedImage into a BufferedImage by creating one and coping - * the contents if it is not, and simply up-casting if it is. + * Convert an abstract image, whose underlying implementation may or may not + * be a BufferedImage into a BufferedImage by creating one and coping the + * contents if it is not, and simply up-casting if it is. + * * @param img The image to convert * @return The converted image */ @@ -35,7 +37,7 @@ public class CardRendererUtils { if (img == null) { return null; } - + // Already a buffered image? if (img instanceof BufferedImage) { return (BufferedImage) img; @@ -52,25 +54,25 @@ public class CardRendererUtils { // Return the buffered image return bimage; } - + // Draw a rounded box with a 2-pixel border // Used on various card parts. public static void drawRoundedBox(Graphics2D g, int x, int y, int w, int h, int bevel, Paint border, Color fill) { g.setColor(new Color(0, 0, 0, 150)); - g.drawOval(x-1, y-1, bevel*2, h); + g.drawOval(x - 1, y - 1, bevel * 2, h); g.setPaint(border); - g.drawOval(x, y, bevel*2-1, h-1); - g.drawOval(x + w - bevel*2, y, bevel*2-1, h-1); - g.drawOval(x+1, y+1, bevel*2-3, h-3); - g.drawOval(x+1 + w - bevel*2, y+1, bevel*2-3, h-3); - g.drawRect(x + bevel, y, w - 2*bevel, h-1); - g.drawRect(x+1 + bevel, y+1, w - 2*bevel-2, h-3); + g.drawOval(x, y, bevel * 2 - 1, h - 1); + g.drawOval(x + w - bevel * 2, y, bevel * 2 - 1, h - 1); + g.drawOval(x + 1, y + 1, bevel * 2 - 3, h - 3); + g.drawOval(x + 1 + w - bevel * 2, y + 1, bevel * 2 - 3, h - 3); + g.drawRect(x + bevel, y, w - 2 * bevel, h - 1); + g.drawRect(x + 1 + bevel, y + 1, w - 2 * bevel - 2, h - 3); g.setColor(fill); - g.fillOval(x+2, y+2, bevel*2-4, h-4); - g.fillOval(x+2 + w - bevel*2, y+2, bevel*2-4, h-4); - g.fillRect(x + bevel, y+2, w - 2*bevel, h-4); + g.fillOval(x + 2, y + 2, bevel * 2 - 4, h - 4); + g.fillOval(x + 2 + w - bevel * 2, y + 2, bevel * 2 - 4, h - 4); + g.fillRect(x + bevel, y + 2, w - 2 * bevel, h - 4); } - + // Get the width of a mana cost rendered with ManaSymbols.draw public static int getManaCostWidth(String manaCost, int symbolSize) { int width = 0; @@ -82,18 +84,19 @@ public class CardRendererUtils { } return width; } - + // Abbreviate a piece of rules text, making substitutions to decrease its // length. Also abbreviate reminder text. private static final Pattern abbreviationPattern; - private static final Map abbreviations = new HashMap(); + private static final Map abbreviations = new HashMap<>(); private static final Pattern killReminderTextPattern; + static { // Available abbreviations abbreviations.put("enters the battlefield", "ETB"); abbreviations.put("less than", "<"); abbreviations.put("greater than", ">"); - + // Compile into regex String patternString = "("; Iterator it = abbreviations.keySet().iterator(); @@ -105,10 +108,11 @@ public class CardRendererUtils { } patternString += ")"; abbreviationPattern = Pattern.compile(patternString); - + // Reminder text killing killReminderTextPattern = Pattern.compile("\\([^\\)]*\\)"); } + public static String abbreviateRule(String rule) { StringBuffer build = new StringBuffer(); Matcher match = abbreviationPattern.matcher(rule); @@ -118,6 +122,7 @@ public class CardRendererUtils { match.appendTail(build); return build.toString(); } + public static String killReminderText(String rule) { return killReminderTextPattern.matcher(rule).replaceAll(""); } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java b/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java index 6cad41a0940..562e1f0c69f 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ModernCardRenderer.java @@ -311,7 +311,7 @@ public class ModernCardRenderer extends CardRenderer { Rectangle2D rect; if (useInventionFrame()) { rect = new Rectangle2D.Float(0, 0, 1, 1); - } else if (cardView.getFrameStyle().isFullArt() || cardView.isToken()) { + } else if (cardView.getFrameStyle().isFullArt() || (cardView.isToken())) { rect = new Rectangle2D.Float(.079f, .11f, .84f, .63f); } else { rect = new Rectangle2D.Float(.079f, .11f, .84f, .42f); @@ -320,7 +320,7 @@ public class ModernCardRenderer extends CardRenderer { } private float getTypeLineYFrac() { - if (cardView.isToken()) { + if (cardView.isToken() && cardView.getCardNumber() == null) { return TYPE_LINE_Y_FRAC_TOKEN; } else if (cardView.getFrameStyle().isFullArt()) { return TYPE_LINE_Y_FRAC_FULL_ART; diff --git a/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java b/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java index e2181c83b2c..d8ad9fae672 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java +++ b/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java @@ -39,6 +39,8 @@ import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.InfoEffect; import mage.cards.Card; +import mage.cards.ExpansionSet; +import mage.cards.Sets; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; @@ -47,6 +49,7 @@ import mage.constants.MultiplayerAttackOption; import mage.constants.Outcome; import mage.constants.PhaseStep; import mage.constants.RangeOfInfluence; +import mage.constants.SetType; import mage.constants.TimingRule; import mage.constants.Zone; import mage.game.command.Emblem; @@ -156,14 +159,26 @@ class MomirEffect extends OneShotEffect { // should this be random across card names, or card printings? CardCriteria criteria = new CardCriteria().types(CardType.CREATURE).convertedManaCost(value); List options = CardRepository.instance.findCards(criteria); - if (options != null && !options.isEmpty()) { - Card card = options.get(RandomUtil.nextInt(options.size())).getCard(); - EmptyToken token = new EmptyToken(); - CardUtil.copyTo(token).from(card); - token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false); - } else { + if (options == null || options.isEmpty()) { game.informPlayers("No random creature card with converted mana cost of " + value + " was found."); + return false; } + EmptyToken token = new EmptyToken(); // search for a non custom set creature + while (token.getName().isEmpty() && !options.isEmpty()) { + int index = RandomUtil.nextInt(options.size()); + ExpansionSet expansionSet = Sets.findSet(options.get(index).getSetCode()); + if (expansionSet == null || expansionSet.getSetType().equals(SetType.CUSTOM_SET)) { + options.remove(index); + } else { + Card card = options.get(index).getCard(); + if (card != null) { + CardUtil.copyTo(token).from(card); + } else { + options.remove(index); + } + } + } + token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false); return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CogworkAssembler.java b/Mage.Sets/src/mage/cards/c/CogworkAssembler.java index a5b9c66a994..0432779b8ba 100644 --- a/Mage.Sets/src/mage/cards/c/CogworkAssembler.java +++ b/Mage.Sets/src/mage/cards/c/CogworkAssembler.java @@ -55,7 +55,7 @@ public class CogworkAssembler extends CardImpl { public CogworkAssembler(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); - + this.subtype.add("Assembly-Worker"); this.power = new MageInt(2); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/g/GontisMachinations.java b/Mage.Sets/src/mage/cards/g/GontisMachinations.java index 4bdb584078e..927a5c8c14c 100644 --- a/Mage.Sets/src/mage/cards/g/GontisMachinations.java +++ b/Mage.Sets/src/mage/cards/g/GontisMachinations.java @@ -124,6 +124,7 @@ class GontisMachinationsFirstLostLifeThisTurnWatcher extends Watcher { public GontisMachinationsFirstLostLifeThisTurnWatcher(final GontisMachinationsFirstLostLifeThisTurnWatcher watcher) { super(watcher); + this.playersLostLife.putAll(watcher.playersLostLife); } @Override diff --git a/Mage.Sets/src/mage/cards/m/MaelstromNexus.java b/Mage.Sets/src/mage/cards/m/MaelstromNexus.java index 2c8609419d4..4542b9e8615 100644 --- a/Mage.Sets/src/mage/cards/m/MaelstromNexus.java +++ b/Mage.Sets/src/mage/cards/m/MaelstromNexus.java @@ -46,7 +46,6 @@ import mage.game.stack.StackObject; import mage.players.Player; import mage.watchers.common.FirstSpellCastThisTurnWatcher; - /** * * @author jeffwadsworth @@ -54,7 +53,7 @@ import mage.watchers.common.FirstSpellCastThisTurnWatcher; public class MaelstromNexus extends CardImpl { public MaelstromNexus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}{U}{B}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{U}{B}{R}{G}"); // The first spell you cast each turn has cascade. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MaelstromNexusGainCascadeFirstSpellEffect()), new FirstSpellCastThisTurnWatcher()); @@ -72,7 +71,7 @@ public class MaelstromNexus extends CardImpl { class MaelstromNexusGainCascadeFirstSpellEffect extends ContinuousEffectImpl { - private Ability cascadeAbility = new CascadeAbility(); + private final Ability cascadeAbility = new CascadeAbility(); public MaelstromNexusGainCascadeFirstSpellEffect() { super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); @@ -106,4 +105,4 @@ class MaelstromNexusGainCascadeFirstSpellEffect extends ContinuousEffectImpl { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/q/QuestForTheGemblades.java b/Mage.Sets/src/mage/cards/q/QuestForTheGemblades.java index adf2f477497..6046544ea3a 100644 --- a/Mage.Sets/src/mage/cards/q/QuestForTheGemblades.java +++ b/Mage.Sets/src/mage/cards/q/QuestForTheGemblades.java @@ -28,7 +28,7 @@ package mage.cards.q; import java.util.UUID; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealsDamageToACreatureAllTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.costs.common.SacrificeSourceCost; @@ -37,13 +37,10 @@ import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.events.DamagedCreatureEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; +import mage.filter.StaticFilters; import mage.target.common.TargetCreaturePermanent; /** @@ -57,7 +54,11 @@ public class QuestForTheGemblades extends CardImpl { // Whenever a creature you control deals combat damage to a creature, you may put a quest counter on Quest for the Gemblades. - this.addAbility(new QuestForTheGembladesTriggeredAbility()); + this.addAbility(new DealsDamageToACreatureAllTriggeredAbility( + new AddCountersSourceEffect(CounterType.QUEST.createInstance()), false, + StaticFilters.FILTER_CONTROLLED_A_CREATURE, + SetTargetPointer.PERMANENT, true)); + // Remove a quest counter from Quest for the Gemblades and sacrifice it: Put four +1/+1 counters on target creature. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance(4)), @@ -76,43 +77,3 @@ public class QuestForTheGemblades extends CardImpl { return new QuestForTheGemblades(this); } } - -class QuestForTheGembladesTriggeredAbility extends TriggeredAbilityImpl { - - public QuestForTheGembladesTriggeredAbility() { - super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.QUEST.createInstance()), true); - } - - public QuestForTheGembladesTriggeredAbility(final QuestForTheGembladesTriggeredAbility ability) { - super(ability); - } - - @Override - public QuestForTheGembladesTriggeredAbility copy() { - return new QuestForTheGembladesTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.DAMAGED_CREATURE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (((DamagedCreatureEvent) event).isCombatDamage()) { - Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent == null) { - permanent = (Permanent) game.getLastKnownInformation(event.getSourceId(), Zone.BATTLEFIELD); - } - if (permanent != null && permanent.getCardType().contains(CardType.CREATURE) && permanent.getControllerId().equals(this.getControllerId())) { - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever a creature you control deals combat damage to a creature, " + super.getRule(); - } -} diff --git a/Mage.Sets/src/mage/cards/t/ToxinSliver.java b/Mage.Sets/src/mage/cards/t/ToxinSliver.java index bf2fdab9b9e..74dd074377c 100644 --- a/Mage.Sets/src/mage/cards/t/ToxinSliver.java +++ b/Mage.Sets/src/mage/cards/t/ToxinSliver.java @@ -29,18 +29,13 @@ package mage.cards.t; import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.DealsDamageToACreatureTriggeredAbility; -import mage.abilities.effects.Effect; +import mage.abilities.common.DealsDamageToACreatureAllTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.target.targetpointer.FixedTarget; +import mage.constants.SetTargetPointer; +import mage.filter.common.FilterCreaturePermanent; /** * @@ -56,7 +51,10 @@ public class ToxinSliver extends CardImpl { this.toughness = new MageInt(3); // Whenever a Sliver deals combat damage to a creature, destroy that creature. It can't be regenerated. - this.addAbility(new DealsDamageToACreatureTriggeredAbility(new DestroyTargetEffect(true), true, false, true)); + this.addAbility(new DealsDamageToACreatureAllTriggeredAbility( + new DestroyTargetEffect(true), false, + new FilterCreaturePermanent("Sliver","a Sliver"), + SetTargetPointer.PERMANENT, true)); } @@ -69,48 +67,3 @@ public class ToxinSliver extends CardImpl { return new ToxinSliver(this); } } - -class DealsDamageTriggeredAbility extends TriggeredAbilityImpl { - - private boolean setTargetPointer; - - public DealsDamageTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer) { - super(Zone.BATTLEFIELD, effect, optional); - this.setTargetPointer = setTargetPointer; - } - - public DealsDamageTriggeredAbility(final DealsDamageTriggeredAbility ability) { - super(ability); - this.setTargetPointer = ability.setTargetPointer; - } - - @Override - public DealsDamageTriggeredAbility copy() { - return new DealsDamageTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.DAMAGED_CREATURE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (game.getPermanent(event.getSourceId()).hasSubtype("Sliver", game)) { - if (setTargetPointer) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(game.getControllerId(event.getTargetId()))); - effect.setValue("damage", event.getAmount()); - } - } - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever a Sliver deals damage to a creature" + super.getRule(); - } - -} diff --git a/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureAllTriggeredAbility.java new file mode 100644 index 00000000000..ee6215d7396 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureAllTriggeredAbility.java @@ -0,0 +1,83 @@ +/* + * 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.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.events.DamagedCreatureEvent; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author Ludwig.Hirth + */ +public class DealsDamageToACreatureAllTriggeredAbility extends TriggeredAbilityImpl { + + private final boolean combatDamageOnly; + private final FilterPermanent filterPermanent; + private final SetTargetPointer setTargetPointer; + + public DealsDamageToACreatureAllTriggeredAbility(Effect effect, boolean optional, FilterPermanent filterPermanent, SetTargetPointer setTargetPointer, boolean combatDamageOnly) { + super(Zone.BATTLEFIELD, effect, optional); + this.combatDamageOnly = combatDamageOnly; + this.setTargetPointer = setTargetPointer; + this.filterPermanent = filterPermanent; + } + + public DealsDamageToACreatureAllTriggeredAbility(final DealsDamageToACreatureAllTriggeredAbility ability) { + super(ability); + this.combatDamageOnly = ability.combatDamageOnly; + this.filterPermanent = ability.filterPermanent; + this.setTargetPointer = ability.setTargetPointer; + } + + @Override + public DealsDamageToACreatureAllTriggeredAbility copy() { + return new DealsDamageToACreatureAllTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.DAMAGED_CREATURE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!combatDamageOnly || ((DamagedCreatureEvent) event).isCombatDamage()) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (permanent != null && filterPermanent.match(permanent, getSourceId(), getControllerId(), game)) { + for (Effect effect : this.getEffects()) { + effect.setValue("damage", event.getAmount()); + effect.setValue("sourceId", event.getSourceId()); + 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; + } + + @Override + public String getRule() { + return "Whenever " + filterPermanent.getMessage() + " deals " + + (combatDamageOnly ? "combat ":"") + "damage to a creature, " + super.getRule(); + } +} \ No newline at end of file diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java index d94837b3c29..6ad4e64c25f 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java @@ -53,7 +53,7 @@ public class SacrificeTargetCost extends CostImpl { target.setNotTarget(true); // sacrifice is never targeted this.text = "sacrifice " + ((target.getNumberOfTargets() != 1 || (target.getTargetName().startsWith("an") || target.getTargetName().startsWith("a "))) - ? "" : "a ") + target.getTargetName(); + ? "" : (target.getTargetName().startsWith("artifact") ? "an " : "a ")) + target.getTargetName(); target.setTargetName(target.getTargetName() + " (to sacrifice)"); } @@ -123,4 +123,4 @@ public class SacrificeTargetCost extends CostImpl { public List getPermanents() { return permanents; } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 082eda39115..310eec34584 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -9,6 +9,7 @@ import mage.constants.CardType; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterArtifactCreaturePermanent; import mage.filter.common.FilterControlledArtifactPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreatureSpell; @@ -25,6 +26,7 @@ public class StaticFilters { public static final FilterCreaturePermanent FILTER_ARTIFACT_CREATURE_PERMANENT = new FilterArtifactCreaturePermanent(); public static final FilterPermanent FILTER_PERMANENT_ARTIFACT_OR_CREATURE = new FilterPermanent("artifact or creature"); public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE = new FilterControlledPermanent("artifact or creature you control"); + public static final FilterControlledPermanent FILTER_CONTROLLED_A_CREATURE = new FilterControlledCreaturePermanent("a creature you control"); public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT = new FilterControlledArtifactPermanent(); public static final FilterArtifactCard FILTER_CARD_ARTIFACT = new FilterArtifactCard(); public static final FilterNonlandCard FILTER_CARD_NON_LAND = new FilterNonlandCard(); diff --git a/Mage/src/main/java/mage/watchers/common/FirstSpellCastThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/FirstSpellCastThisTurnWatcher.java index 9fc4586732f..145bd9abf05 100644 --- a/Mage/src/main/java/mage/watchers/common/FirstSpellCastThisTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/FirstSpellCastThisTurnWatcher.java @@ -12,7 +12,8 @@ import mage.watchers.Watcher; /** * @author jeffwadsworth -**/ +* + */ public class FirstSpellCastThisTurnWatcher extends Watcher { private final Map playerFirstSpellCast = new HashMap<>(); @@ -24,6 +25,8 @@ public class FirstSpellCastThisTurnWatcher extends Watcher { public FirstSpellCastThisTurnWatcher(final FirstSpellCastThisTurnWatcher watcher) { super(watcher); + playerFirstSpellCast.putAll(watcher.playerFirstSpellCast); + playerFirstCastSpell.putAll(watcher.playerFirstSpellCast); } @Override @@ -61,4 +64,4 @@ public class FirstSpellCastThisTurnWatcher extends Watcher { return playerFirstSpellCast.get(playerId); } } -} \ No newline at end of file +}