diff --git a/Mage.Sets/src/mage/sets/shardsofalara/GatherSpecimens.java b/Mage.Sets/src/mage/sets/shardsofalara/GatherSpecimens.java index 16814c8f482..5658b200590 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/GatherSpecimens.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/GatherSpecimens.java @@ -37,10 +37,10 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; +import mage.players.Player; /** * @@ -71,8 +71,6 @@ public class GatherSpecimens extends CardImpl { class GatherSpecimensReplacementEffect extends ReplacementEffectImpl { - private static final FilterCreatureCard filter = new FilterCreatureCard(); - public GatherSpecimensReplacementEffect() { super(Duration.EndOfTurn, Outcome.GainControl); staticText = "If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead"; @@ -94,25 +92,31 @@ class GatherSpecimensReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - Card card = game.getCard(((ZoneChangeEvent) event).getTargetId()); - if (card != null) { - card.putOntoBattlefield(game, zEvent.getFromZone(), zEvent.getSourceId(), source.getControllerId(), zEvent.comesIntoPlayTapped(), zEvent.getAppliedEffects()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + event.setPlayerId(controller.getId()); } - return true; + return false; } @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) { - Card card = game.getCard(((ZoneChangeEvent) event).getTargetId()); - if (card != null && filter.match(card, source.getSourceId(), source.getControllerId(), game)) { - if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + Card card = game.getCard(event.getTargetId()); + if (card.getCardType().contains(CardType.CREATURE)) { // TODO: Bestow Card cast as Enchantment probably not handled correctly + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) { return true; } } } + if (event.getType() == GameEvent.EventType.CREATE_TOKEN && event.getFlag()) { // flag indicates if it's a creature token + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) { + return true; + } + } return false; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/GatherSpecimensTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/GatherSpecimensTest.java index 82eca043f2c..bc88cda16f8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/GatherSpecimensTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/GatherSpecimensTest.java @@ -41,6 +41,27 @@ public class GatherSpecimensTest extends CardTestPlayerBase { assertPermanentCount(playerB, "Memnite", 0); } + @Test + public void testTokenCreatedFromSpellEffect() { + + addCard(Zone.BATTLEFIELD, playerA, "Island", 6); + addCard(Zone.HAND, playerA, "Gather Specimens", 1); + + addCard(Zone.BATTLEFIELD, playerB, "Plains", 3); + addCard(Zone.HAND, playerB, "Spectral Procession", 1); + + castSpell(2, PhaseStep.UPKEEP, playerA, "Gather Specimens"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Spectral Procession"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + + execute(); + + assertPermanentCount(playerA, "Spirit", 3); + assertPermanentCount(playerB, "Spirit", 0); + + } @Test public void testFromGraveyardEffect() { @@ -83,6 +104,7 @@ public class GatherSpecimensTest extends CardTestPlayerBase { castSpell(1, PhaseStep.UPKEEP, playerA, "Gather Specimens"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Oblivion Ring"); + addTarget(playerA, "Memnite"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Disenchant", "Oblivion Ring"); @@ -94,4 +116,6 @@ public class GatherSpecimensTest extends CardTestPlayerBase { assertPermanentCount(playerB, "Memnite", 0); } + + } diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index 1d01a7fbb5f..d7162cfcd94 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -377,7 +377,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } break; case BATTLEFIELD: - PermanentCard permanent = new PermanentCard(this, ownerId); + PermanentCard permanent = new PermanentCard(this, event.getPlayerId()); // controller can be replaced (e.g. Gather Specimens) game.resetForSourceId(permanent.getId()); game.addPermanent(permanent); game.setZone(objectId, Zone.BATTLEFIELD); @@ -399,7 +399,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { .append("] source [").append(sourceCard != null ? sourceCard.getName():"null").append("]").toString()); return false; } - setControllerId(ownerId); + setControllerId(event.getPlayerId()); game.setZone(objectId, event.getToZone()); game.addSimultaneousEvent(event); return game.getState().getZone(objectId) == toZone; @@ -543,11 +543,11 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } } updateZoneChangeCounter(); - PermanentCard permanent = new PermanentCard(this, controllerId); + PermanentCard permanent = new PermanentCard(this, event.getPlayerId()); // reset is done to end continuous effects from previous instances of that permanent (e.g undying) game.resetForSourceId(permanent.getId()); // make sure the controller of all continuous effects of this card are switched to the current controller - game.getContinuousEffects().setController(objectId, controllerId); + game.getContinuousEffects().setController(objectId, event.getPlayerId()); game.addPermanent(permanent); game.setZone(objectId, Zone.BATTLEFIELD); game.setScopeRelevant(true); @@ -555,7 +555,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { permanent.entersBattlefield(sourceId, game, event.getFromZone(), true); game.setScopeRelevant(false); game.applyEffects(); - game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD)); + game.fireEvent(new ZoneChangeEvent(permanent, event.getPlayerId(), fromZone, Zone.BATTLEFIELD)); return true; } return false; diff --git a/Mage/src/mage/game/events/GameEvent.java b/Mage/src/mage/game/events/GameEvent.java index 17cba4e1d8b..b0f54b6e0b4 100644 --- a/Mage/src/mage/game/events/GameEvent.java +++ b/Mage/src/mage/game/events/GameEvent.java @@ -186,6 +186,10 @@ public class GameEvent { return sourceId; } + public void setPlayerId(UUID playerId) { + this.playerId = playerId; + } + public UUID getPlayerId() { return playerId; } diff --git a/Mage/src/mage/game/permanent/token/Token.java b/Mage/src/mage/game/permanent/token/Token.java index 5be4264b9b7..1be1d48910f 100644 --- a/Mage/src/mage/game/permanent/token/Token.java +++ b/Mage/src/mage/game/permanent/token/Token.java @@ -139,11 +139,11 @@ public class Token extends MageObjectImpl { } else { setCode = source != null ? source.getExpansionSetCode() : null; } - GameEvent event = GameEvent.getEvent(EventType.CREATE_TOKEN, null, sourceId, controllerId, amount); + GameEvent event = new GameEvent(EventType.CREATE_TOKEN, null, sourceId, controllerId, amount, this.getCardType().contains(CardType.CREATURE)); if (!game.replaceEvent(event)) { amount = event.getAmount(); for (int i = 0; i < amount; i++) { - PermanentToken newToken = new PermanentToken(this, controllerId, setCode, game); + PermanentToken newToken = new PermanentToken(this, event.getPlayerId(), setCode, game); // use event.getPlayerId() because it can be replaced by replacement effect game.getState().addCard(newToken); game.addPermanent(newToken); if (tapped) { @@ -156,7 +156,7 @@ public class Token extends MageObjectImpl { newToken.entersBattlefield(sourceId, game, Zone.OUTSIDE, true); game.setScopeRelevant(false); game.applyEffects(); - game.fireEvent(new ZoneChangeEvent(newToken, controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD)); + game.fireEvent(new ZoneChangeEvent(newToken, event.getPlayerId(), Zone.OUTSIDE, Zone.BATTLEFIELD)); if (attacking && game.getCombat() != null) { game.getCombat().addAttackingCreature(newToken.getId(), game); }